Giter VIP home page Giter VIP logo

libhydrogen's Introduction

Build status CodeQL scan Financial Contributors on Open Collective Coverity Scan Build Status TrustInSoft CI

libhydrogen

The Hydrogen library is a small, easy-to-use, hard-to-misuse cryptographic library.

Features:

  • Consistent high-level API, inspired by libsodium. Instead of low-level primitives, it exposes simple functions to solve common problems that cryptography can solve.
  • 100% built using just two cryptographic building blocks: the Curve25519 elliptic curve, and the Gimli permutation.
  • Small and easy to audit. Implemented as one tiny file for every set of operation, and adding a single .c file to your project is all it takes to use libhydrogen in your project.
  • The whole code is released under a single, very liberal license (ISC).
  • Zero dynamic memory allocations and low stack requirements (median: 32 bytes, max: 128 bytes). This makes it usable in constrained environments such as microcontrollers.
  • Portable: written in standard C99. Supports Linux, *BSD, MacOS, Windows, and the Arduino IDE out of the box.
  • Can generate cryptographically-secure random numbers, even on Arduino boards.
  • Attempts to mitigate the implications of accidental misuse, even on systems with an unreliable PRG and/or no clock.

Non-goals:

  • Having multiple primitives serving the same purpose, even to provide compatibility with other libraries.
  • Networking -- but a simple key exchange API based on the Noise protocol is available, and a STROBE-based transport API will be implemented.
  • Interoperability with other libraries.
  • Replacing libsodium. Libhydrogen tries to keep the number of APIs and the code size down to a minimum.

The documentation is maintained in the libhydrogen wiki.

The legacy libhydrogen code (leveraging XChaCha20, SipHashX, BLAKE2SX, Curve25519) remains available in the v0 branch.

Contributors

Code Contributors

This project exists thanks to all the people who contribute. [Contribute].

libhydrogen's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libhydrogen's Issues

Porting to STM32 - what should hydro_random_init() do?

Hello, I'm hoping to use LibHydrogen on an STM32L471 microcontroller. My compiler reports the error "Unsupported Platform" in random.h. It appears that I'll need to supply my own hydro_random_init() function. Could you please tell me what it should do? The microcontroller has a built-in hardware random number generator, if that helps. Thanks.

Structure of hydro_secretbox_encrypt output

First of all, thank you for a great library!

I am integrating libhydrogen into my project, and I am noticed one thing which I can't understand.

When hydro_secretbox_encrypt_iv constructs packet, it leaves gimli_RATE bytes in the buffer untouched.
siv is filled in with
mem_cpy(siv, buf + gimli_RATE, hydro_secretbox_SIVBYTES - gimli_RATE);
and mac starts only from hydro_secretbox_SIVBYTES.
With default defines it gives 16 unused bytes in every packet.
Is there any reasoning for this?
Is it safe to move mac & the rest of the packet 16 bytes to the left to close hole?

Why does hash have a minimum size?

Why does hydro_hash_BYTES_MIN exist?
For a bloom filter I only want a 32 bit hash: why is there a 128 bit minimum on output hash size?

Few "minor" issues (ASAN / -Wshadow)

Hi Frank,

nice work so far 👍, looks very promising.

A few minor issues I've catched so far:

  1. https://github.com/jedisct1/libhydrogen/blob/master/impl/x25519.h#L148-L153
    this shadows a previous declared variable and discards const. not sure if you wanted to assign another variable but that would make |mand| unused.

  2. from running the tests, I was able to trigger a global-buffer-overflow [1] and a stack-buffer-overflow [2] both in load32_le's call to memcpy.

[1]

==4659==ERROR: AddressSanitizer: global-buffer-overflow on address 0x0000013b28e0 at pc 0x0000004f989c bp 0x7fffd1c70a10 sp 0x7fffd1c70a08
READ of size 4 at 0x0000013b28e0 thread T0
    #0 0x4f989b in load32_le /home/daniel/code/git/mirror/libhydrogen/impl/common.h:82:5
    #1 0x4f989b in hydro_stream_chacha20_xor /home/daniel/code/git/mirror/libhydrogen/impl/stream.h:90
    #2 0x4f8c43 in randombytes_random /home/daniel/code/git/mirror/libhydrogen/impl/random.h:195:9
    #3 0x4f9964 in randombytes_buf /home/daniel/code/git/mirror/libhydrogen/impl/random.h:228:13
    #4 0x4f5f1f in test_core /home/daniel/code/git/mirror/libhydrogen/tests/tests.c:156:5
    #5 0x4f5f1f in main /home/daniel/code/git/mirror/libhydrogen/tests/tests.c:280
    #6 0x7fa3d74862b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
    #7 0x41c8c9 in _start (/home/daniel/code/git/mirror/libhydrogen/build/tests/tests+0x41c8c9)

0x0000013b28e0 is located 32 bytes to the left of global variable 'hydro_random_initialized' defined in '/home/daniel/code/git/mirror/libhydrogen/hydrogen.c' (0x13b2900) of size 1
0x0000013b28e0 is located 0 bytes to the right of global variable 'hydro_random_key' defined in '/home/daniel/code/git/mirror/libhydrogen/impl/random.h:1:16' (0x13b28c0) of size 32
SUMMARY: AddressSanitizer: global-buffer-overflow /home/daniel/code/git/mirror/libhydrogen/impl/common.h:82:5 in load32_le
Shadow bytes around the buggy address:
  0x00008026e4c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008026e4d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008026e4e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008026e4f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008026e500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x00008026e510: 00 04 f9 f9 f9 f9 f9 f9 00 00 00 00[f9]f9 f9 f9
  0x00008026e520: 01 f9 f9 f9 f9 f9 f9 f9 00 00 00 00 00 00 00 00
  0x00008026e530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008026e540: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008026e550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008026e560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==4659==ABORTING

[2]

==4725==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7f5f318030e0 at pc 0x0000004f988c bp 0x7ffde857ae10 sp 0x7ffde857ae08
READ of size 4 at 0x7f5f318030e0 thread T0
    #0 0x4f988b in load32_le /home/daniel/code/git/mirror/libhydrogen/impl/common.h:82:5
    #1 0x4f988b in hydro_stream_chacha20_xor /home/daniel/code/git/mirror/libhydrogen/impl/stream.h:90
    #2 0x4f60c1 in test_hash /home/daniel/code/git/mirror/libhydrogen/tests/tests.c:73:5
    #3 0x4f60c1 in main /home/daniel/code/git/mirror/libhydrogen/tests/tests.c:281
    #4 0x7f5f345dc2b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
    #5 0x41c8c9 in _start (/home/daniel/code/git/mirror/libhydrogen/build/tests/tests+0x41c8c9)

Address 0x7f5f318030e0 is located in stack of thread T0 at offset 12512 in frame
    #0 0x4f5b0f in main /home/daniel/code/git/mirror/libhydrogen/tests/tests.c:274

  This frame has 26 object(s):
    [32, 532) 'msg.i53'
    [608, 672) 'sig.i'
    [704, 848) 'st.i54'
    [912, 976) 'kp.i'
    [1008, 1033) 'm.i'
    [1072, 1097) 'm2.i'
    [1136, 1197) 'c.i'
    [1232, 11232) 'tmp.i'
    [11488, 11520) 'subkey3.i'
    [11552, 11602) 'subkey4.i'
    [11648, 11681) 'subkey2_hex.i'
    [11728, 11793) 'subkey3_hex.i'
    [11840, 11941) 'subkey4_hex.i'
    [11984, 12032) 'st.i6'
    [12064, 12080) 'h.i'
    [12096, 12112) 'key.i8'
    [12128, 12161) 'hex.i10'
    [12208, 12352) 'st.i'
    [12416, 12448) 'dk.i'
    [12480, 12512) 'key.i' <== Memory access at offset 12512 overflows this variable
    [12544, 13544) 'msg.i'
    [13680, 13780) 'x.i'
    [13824, 13924) 'y.i'
    [13968, 13973) 'a.i'
    [14000, 14005) 'b.i'
    [14032, 14233) 'hex.i'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /home/daniel/code/git/mirror/libhydrogen/impl/common.h:82:5 in load32_le
Shadow bytes around the buggy address:
  0x0fec662f85c0: 00 00 01 f2 f2 f2 f2 f2 00 00 00 00 00 00 00 00
  0x0fec662f85d0: 00 00 00 00 05 f2 f2 f2 f2 f2 00 00 00 00 00 00
  0x0fec662f85e0: f2 f2 f2 f2 00 00 f2 f2 00 00 f2 f2 00 00 00 00
  0x0fec662f85f0: 01 f2 f2 f2 f2 f2 00 00 00 00 00 00 00 00 00 00
  0x0fec662f8600: 00 00 00 00 00 00 00 00 f2 f2 f2 f2 f2 f2 f2 f2
=>0x0fec662f8610: 00 00 00 00 f2 f2 f2 f2 00 00 00 00[f2]f2 f2 f2
  0x0fec662f8620: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fec662f8630: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fec662f8640: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fec662f8650: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fec662f8660: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==4725==ABORTING

HTH!

Bindings

Hi,

I'm hoping to use libhydrogen for an ESP8266-based project. I have successfully integrated most methods on the ESP, and wrote a C++ utility to sign/encrypt payloads for testing. But now we're working on integration and the lack of php or python bindings is unfortunate. I can probably write a python module, but neither I nor my colleague have experience writing a php extension from scratch. I thought phosphine would be at least a start, but it appears to be just a skeleton with nothing actually implemented.

Looking at your other repo libsodium-php it looks like there might be a good amount of overlap in a libhydrogen port. So, is there any effort or plans for a port for libhydrogen?

Public Key / Box Encryption?

Is this library going to support Public Key / NaCl Box Encryption?
Was looking at the wiki:
image

And I'm not sure if Public Key Encryption can be built from these things?
Is this one of the non-goals?
I saw on the readme that

The legacy libhydrogen code (leveraging XChaCha20, SipHashX, BLAKE2SX, Curve25519) remains available in the v0 branch.

and I know that Curve25519 is used in NaCl Box Encryption. so.. idk. 🤷‍♂️

Typo

File hydrogen.h, line 28, case of "x":
__declspec(align(x)) -> __declspec(align(X))

Add Hydride

Creator of Lazysodium here. Thank you for creating this library - I love the focus on portability.

I have created another binding for Java, Hydride, that works across many platforms running Java.

Please add it to the bindings list. Thank you in advance!

Secure network communications

Hey Frank! First of all, thank you for this crypto library. I really like the Hydrogen, and at the moment I'm integrating it into my new networking layer. Since I'm not familiar with this library, I want to make sure that I did everything right, so please, take a look at this scheme based on N variant key exchange:

  1. A client connected to a server, and new public key generated for this client using hydro_kx_keygen
  2. Public key sent to the client without any encryption to generate session keys using hydro_kx_n_1
  3. Client send generated packet without any encryption to the server to compute session keys using hydro_kx_n_2
  4. Now we can compute a secret key using hydro_secretbox_keygen and securely exchange encrypted messages using hydro_secretbox_encrypt and hydro_secretbox_decrypt

Did I do everything right? Any tips, please?

Unable to initialize on Android

Hi, thank you for this library! I am trying to build it to run on android. The build process was successful, but the library wont initialize; I am building using android NDK. I made a post on stackoverflow where there is more specific detail to my problem.

Generating same secretbox key

Calling hydro_secretbox_keygen in a new process gets the same result every time.

Delving into the code, this appears to be because hydro_random_buf doesn't call hydro_random_check_initialized

deterministic signatures?

I'm wondering whether this is something that would be considered, either via a build flag or additional function(s) in the hydro_sign interface, for situations where a deterministic signature is preferable.

hydro_pwhash_create without a master key

I understand the password-hashing API is designed to prevent misuse in the most common cases. But I'm using it to create a hash on a network client which is then transmitted—encrypted, in a secretbox—to a server, which verifies the hash against a password it already holds in plaintext. None of this data is ever stored. Therefore, encrypting the password hash only to wrap it in the transport encryption feels excessive, and requires that I derive a second key just for the password hash.

Error in wiki

in Public-key-signatures

#define hydro_sign_SECRETKEYBYTES 32

look wrong

Unable to compile random.h on a teensy chip

Temp\arduino_build_987748\sketch\impl/random.h:35:5: error: 'MCUSR' undeclared (first use in this function)

     MCUSR = 0;


I'm pretty new on Arduino, is there a library I'm missing or any inclusion?

PlatformIO library integration

It would be really convenient if this library was listed in the library manager of platformio. As far as I understand, you would only need to add one json file with meta data. More information can be found here:
http://docs.platformio.org/en/latest/librarymanager/creating.html

So far, I am manually cloning this repo, the automatic build system of platformio does the rest and all just works. To reach more users and for automatic dependency management to work an integration into the library manager is still desirable.

Thanks and keep up the great work!

Encryption with public key then decryption with private key

Hi again,

I read the doc, but I'm trying to do something customized.
I need:

  • Something so that I can encode with the PUB public key but can't decrypt the stream with the same PUB key.
  • When something is encrypted with the PUB key, it can be decrypted with the PRV private key.

I also need the reciprocity (something encoded with PRV is decryptable by the PUB)

Is it something I can do with your library?

Thanks,

error compiling with mingw

Hello, I've been trying to compile with mingw (gcc version is 4.8.1) on Windows 7 64-bit.
"make lib" works, but for "make all" I get the error "undefined reference to `SystemFunction036@8'". I get the same error if I try to compile libhydrogen.a into a program of my own.
Can you tell me how to correct this?
Thanks

STM32F4 support

Is there a way how to get libhydrogen running on STM32F4 processor?

Hash strength

While the output length of the hash function is virtually unlimited, nowhere in the documentation can I find a quote for the cryptographic strength of the hash.

As best I can tell by looking at the code the strength for 256 bits or longer output is: 128 bits collision, 128 bits second preimage and somewhere in the range 128 to 256 bits first preimage. Where an ideal 256 bit hash function would provide 128, 256 and 256 bits of strength.

The strength of the hash should be documented.

For future releases I'd consider improving the hash to be at least an ideal 256 bit hash. I also wonder about the purpose of providing longer hashes when the strength of the underlying algorithm stays the same, one would think a longer output means better security, that just isn't the case here.

What is HYDRO_HWTYPE for?

It's set by Makefile.arduino, and default-initialized in hydrogen.h, but I can't find any place it's actually used.

Question on Gimli

Hi and sorry I'm asking here, but did not find a better place to ask dumb questions.

In the spec https://gimli.cr.yp.to/spec.html it is said that the second step in the non-linear layer is

x = x ^ (z << 1) ^ ((y&z) << 2);
y = y ^ x        ^ ((x|z) << 1);
z = z ^ y        ^ ((x&y) << 3);

BUT

in the reference code below we see that

      x = rotate(state[    column], 24);
      y = rotate(state[4 + column],  9);
      z =        state[8 + column];

      state[8 + column] = x ^ (z << 1) ^ ((y&z) << 2);
      state[4 + column] = y ^ x        ^ ((x|z) << 1);
      state[column]     = z ^ y        ^ ((x&y) << 3);

If you take a look at

z = state[8 + column];

and then

 state[8 + column] = x ^ (z << 1) ^ ((y&z) << 2);

it turns out that actually it's
it's

      z = x ^ (z << 1) ^ ((y&z) << 2);
      y = y ^ x        ^ ((x|z) << 1);
      x = z ^ y        ^ ((x&y) << 3);

Am I missing something?

How close to production is libhydrogen?

Not looking for complete whitepaper set-in-stone blueprints in regard to this question, but merely the authors' opinion.

How likely to change is the API? Do you want [complete] freedom to change the API at this stage? And/or could you speculate if it might need to change its API (purposefully or unpurposefully)?

I see there are no formal github releases yet. Does that mean this is still mostly work-in-progress, wait for 0.1 for some kind of API stability?

Are you working towards a 0.1 or 1.0 release at the moment, have any kind of projections for how close that is?

TL;DR - looking for clarifications for what expectations outsiders should have for "when should I use libhydrogen for my [personal / prototype / production / library] project?"

Thanks!

Please mark versions

Hello @jedisct1

May I request you to start maintaining version tags and releases for this library, like with libsodium. It makes things easy for filing bugs, discussing improvements and generally referencing, instead of using raw git commit IDs.

Thanks

hydro_random_rbit

I want to use this library with a STM32 microcontroller which doesn't have an RNG so the suggestion from #40 won't work for me.

For implementing hydro_random_init I'm planning to use the ADC values and a counter (like in Arduino variant) driven by LSI clock (LSI has very low accuracy, which is valuable for some randomness).

I want to base my port on Arduino's variant, and something caught my eye. There are no comments so I can't tell whether it's supposed to be this way or this is an error:

static bool
hydro_random_rbit(unsigned int x)
{
    size_t i;
    bool   res = 0;

    for (i = 0; i < sizeof x; i++) {
        res ^= ((x >> i) & 1);
    }
    return res;
}

sizeof returns the number of bytes, not bits. Maybe this was supposed to be this way:

...
    for (i = 0; i < 8 * sizeof x; i++) {
...

BTW, I'm open to suggestions with hydro_random_init implementation for RNG-less STM32 if you think that the mentioned approach isn't good enough. Thank you.

[Query/Advice] Confusion about signing/key exchange keys and usage.

Apologies if this is not the correct forum for such a question, directions to a more appropriate forum welcome (I would have posted on stackoverflow, but github seems to have recent activity by the author)

Are both hydro_sign_keypair, and hydro_sign_keypair equivalent ?
I assume both are Curve25519 keys, as their sizes are the same.

Is there some reason they have different names, other than for readability?

Finally, are there any reasons (if they are equivalent) not to share the keypair between both signing and key exchange functions?

Proposal: simplify / improve secretbox construction

Hi Frank, I'm currently implementing secretbox for the Go implementation of libhydrogen.
I noticed the following:
This is encryption scheme you use for secretbox:

Input: msg, msg_id, ctxt, key

kmac || kn || kenc = ChaCha12(n = (msg_id || {0}), k = key)
k0                 = SipHash(m = msg, ctxt, k=kn) ^ random_data
nonce              = HChaCha12(n = {0}, k = k0)
e                  = XChaCha12(m = msg, n = (nonce || {0}), k = kenc)
mac                = SipHash( m = (n || e), ctxt, k = kmac)
c                  = n || mac || e

My suggestion would be:
Replace the computation of k0 as the MAC of the message (with kn) and using k0 to generate the nonce for the XChaCha12 encryption with: nonce = kn ^ random
This would lead to:

Input: msg, msg_id, ctxt, key

kmac || kn || kenc = ChaCha12(m={0}, n={0}||id, k=key)
nonce              = kn ^ random_data
e                  = XChaCha12(m=msg, n=nonce, kenc)
mac                = Siphash(m= (random_data || e), ctx, kmac)
c                  = mac || random_data || e  

This construction would lead to better performance, because the SipHash-MAC needn't computed twice.
Also every ciphertext would be different, even if the same message is encrypted twice (and no msg_ids are used). If msg_ids are used, random_data could theoretically be a fixed value - but I think it would reduce complexity (for the users and implementors) and be more consistent to assume that random_data is always random.

Furthermore random_data can be 20 bytes long to keep the overhead of 36 bytes or it can be reduced to 16 bytes (without risking duplications with higher prob. than 2^64) - than the overhead would be 32 bytes.
For a overhead of 36 bytes: nonce = kn[0:4] || (kn[4:16] ^ random_data[0:12]) || random[12:20]
For a overhead of 32 bytes: nonce = kn[0:8] || (kn[8:16] ^ random_data[0:8]) || random[8:16]

Gimli test vectors are not satisfied for the portable implementation

I think your portable implementation of Gimli is wrong.

When using test vectors :

00000000 9e3779ba 3c6ef37a daa66d46 
78dde724 1715611a b54cdb2e 53845566 
f1bbcfc8 8ff34a5a 2e2ac522 cc624026 

you get :

248d65cc 93af60b6 d8518d57 8c5c2da7 
15501de2 38f6accb 5ab3d18c b8cea71a 
8ddf7daf 21f4db33 60aec38f 96083e81 

instead of :

ba11c85a 91bad119 380ce880 d24c2c68 
3eceffea 277a921c 4f73a0bd da5a9cd8 
84b673f0 34e52ff7 9e2bef49 f41bb8d6 

This is due to the fact that you are doing :

  • s.s.s.s for small swap instead of s...s...s...
  • .S.S.S.S for big swap instead of ..S...S...S...

BLAKE2X: BLAKE2s produces wrong hash value for zero msg

Following test:

static void
test_hash(void)
{
    hydro_hash_state st;
    uint8_t          ctx[8];
    uint8_t          h[32];
    uint8_t          key[hydro_hash_KEYBYTES_MAX];
    uint8_t          msg[1];
    char             hex[32 * 2 + 1];
    size_t           i;

    memset(msg, 0, sizeof msg);
    memset(ctx, 0, sizeof ctx);

    for (i = 0; i < sizeof key; i++) {
        key[i] = (uint8_t) i;
    }
    hydro_bin2hex(hex, sizeof hex, key, sizeof key);    
    assert(
        hydro_equal("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
        hex, sizeof hex));

    hydro_hash_init(&st, ctx, key, sizeof key, sizeof h);   
    hydro_hash_update(&st, msg, 0); // without this update call, the test fails too!
    hydro_hash_final(&st, h, sizeof h);
    hydro_bin2hex(hex, sizeof hex, h, sizeof h);

    // Test vectors 0 from https://blake2.net/blake2s-test.txt 
     assert(
        hydro_equal("48a8997da407876b3d79c0d92325ad3b89cbb754d86ab71aee047ad345fd2c49",
        hex, sizeof hex));

    // hex now contains: "59d9495d33c17c9980c68d5e4b7d1f3ae61c8487ceca0f43531d73d2098f740d"
}

int
main(void)
{
    int ret;

    ret = hydro_init();
    assert(ret == 0);

    test_hash();

    return 0;
}

fails, while this test passes successfully:

static void
test_hash(void)
{
    hydro_hash_state st;
    uint8_t          ctx[8];
    uint8_t          h[32];
    uint8_t          key[hydro_hash_KEYBYTES_MAX];
    uint8_t          msg[1];
    char             hex[32 * 2 + 1];
    size_t           i;

    memset(msg, 0, sizeof msg);
    memset(ctx, 0, sizeof ctx);

    for (i = 0; i < sizeof key; i++) {
        key[i] = (uint8_t) i;
    }
    hydro_bin2hex(hex, sizeof hex, key, sizeof key);    
    assert(
        hydro_equal("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
        hex, sizeof hex));

    hydro_hash_init(&st, ctx, key, sizeof key, sizeof h);   
    hydro_hash_update(&st, msg, 1); // without this update call, the test fails too!
    hydro_hash_final(&st, h, sizeof h);
    hydro_bin2hex(hex, sizeof hex, h, sizeof h);

    // Test vectors 1 from https://blake2.net/blake2s-test.txt 
     assert(
        hydro_equal("40d15fee7c328830166ac3f918650f807e7e01e177258cdc0a39b11f598066f1",
        hex, sizeof hex));
}

Created Dockerfile for using libhydrogen in images

I just wanted to share that I've created a simple Dockerfile for including this library in Docker images since it's missing package manager support on the common Linux distributions.

Dockerfile:

FROM gcc:latest
WORKDIR /usr/src/libhydrogen
RUN git clone https://github.com/jedisct1/libhydrogen.git . && make install CFLAGS='-fPIC'

The CFLAGS='fPIC' is needed for it to work with Python bindings (pyhy module), though I'll remove this if PR #23 is integrated.

I also have a Dockerhub repository for it at https://hub.docker.com/r/ryanbreaker/libhydrogen with instructions on how to use it. Please feel free to add either of these to the project documentation if you feel it'll help users.

uint8_t is optional in stdint.h

The standard doesn't require it to exist, and some microcontrollers that do support C99 and the other fixed-width types do not have uint8_t. I wanted to get feedback on eliminating the use of uint8_t in favor of unsigned char.

I believe that with some minor changes libhydrogen can be made to work on platforms that don't have an 8-bit integer type, but this would be a prerequisite to that.

cannot load existing libsodium key

there doesnt appear to be any api to load an existing private key for ed25519.

hydro_sign_keygen_deterministic behaves different than libsodiums crypto_sign_ed25519_seed_keypair so the both cant be compatible

Minimising header size

Taking a glance at the secret box code, I didn't figure out if msg_id and the context are actually taking up 8 bytes of message header.
I'm designing for a situation with very small messages, so header size matters.

Signature Verification Only?

I have an application that only needs to verify a signature in the embedded system (all signing is done on servers). It seems to me I could further reduce the footprint if I could prune everything but what is needed for 'hydro_sign_verify'.

A switch for this would be a nice addition, unless I'm missing some other way to easily prune the resulting code.

Sending data from server -> client with NOISE_N is unsafe

The documentation for hydro_kx_n_* suggests that, after a key exchange is performed, one of the generated session keys can be used to safely send data from the server (Noise "responder") and client (Noise "initiator").

// Done! session_kp.tx is the key for sending data to the server,
// and session_kp.rx is the key for receiving data from the server.
// Done! session_kp.tx is the key for sending data to the client,
// and session_kp.rx is the key for receiving data from the client.
// The session keys are the same as those computed by the client, but swapped.

The type signatures of hydro_kx_n_1 and hydro_kx_n_2—returning a key pair instead of a single session key—also suggest this.

However, the Noise specification's description of one-way handshake patterns strongly warns against this:

Following a one-way handshake the sender [client/initiator] can send a stream of transport messages, encrypting them using the first CipherState returned by Split(). The second CipherState from Split() is discarded - the recipient [server/responder] must not send any messages using it (as this would violate the rules in Section 7.3).

The rule referred to in 7.3 is:

Noise relies on DH outputs involving ephemeral keys to randomize the shared secret keys. Patterns failing this check could result in catastrophic key reuse, because the victim might send a message encrypted with a key that doesn't include a contribution from their local ephemeral key (or where the contribution from their local ephemeral was nullified by an invalid ephemeral from the other party).

In other words, the server sending a message back to the client using one of the computed session keys is bad because there's no random contribution on its part to the generation of the session keys. An active attacker could supply the same ephemeral key multiple times, resulting in key reuse. To do this safely, you'd instead want an interactive NOISE_NK handshake.

Please let me know if I've misinterpreted something here. Otherwise, the documentation should surely be updated, and (if changing the type signature is acceptable) hydro_kx_n_* should provide a single client→server session key rather than a key pair, to avoid misuse.

Schnorr signatures

For a project, I'm looking for an implementation of Schnorr Signatures to store many signatures within a small constant size.

Is this something that would fit into libhydrogen?

test_sign: Assertion `hydro_sign_verify(sig, msg, sizeof msg, ctx, kp.pk) == 0' failed.

As discussed on twitter:

With jedisct1/libhydrogen/master:

$ git diff
diff --git a/Makefile b/Makefile
index 12f9e80..85eb1fc 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-WFLAGS ?= -Wall -Wextra -Wmissing-prototypes -Wdiv-by-zero -Wbad-function-cast -Wcast-align -Wcast-qual -Wfloat-equal -Wmissing-declarations -Wnested-externs -Wno-unknown-pragmas -Wpointer-arith -Wredundant-decls -Wstrict-prototypes -Wswitch-enum -Wno-type-limits
+WFLAGS ?= -Wall -Wextra -Wmissing-prototypes -Wdiv-by-zero -Wbad-function-cast -Wcast-align -Wcast-qual -Wfloat-equal -Wmissing-declarations -Wnested-externs -Wno-unknown-pragmas -Wpointer-arith -Wredundant-decls -Wstrict-prototypes -Wswitch-enum -Wno-type-limits -ggdb
 CFLAGS ?= -Os -fno-exceptions $(WFLAGS)
 CFLAGS += -I.
 OBJ = hydrogen.o

$ make test
rm -f tests/tests.done
tests/tests && touch tests/tests.done
tests: tests/tests.c:236: test_sign: Assertion `hydro_sign_verify(sig, msg, sizeof msg, ctx, kp.pk) == 0' failed.
Aborted
Makefile:29: recipe for target 'test' failed
make: *** [test] Error 134

ENV: debian testing, Linux x86_64, gcc 6.3.0 / clang-5.0 (recent decent git)

CPU Flags (8x Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz):

fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm rdseed adx smap xsaveopt arat
bugs

Mbed compilator - error

I tried to compile libhydrogen on Mbed OS, but unfortunately I get this error:

[Error] @,: ARMC6 does not support ARM architecture v7 targets
[Warning] @,: Compiler version mismatch: Could not detect version; expected version >= 6.10 and < 7.0
Building project mbed-os-empty (NUCLEO_F429ZI, ARMC6)
Scan: mbed-os-empty
Link: mbed-os-empty
Warning: L3912W: Option 'legacyalign' is deprecated.
Error: L6200E: Symbol hydro_sign_verify multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_kk_3 multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_hash_init multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_secretbox_probe_create multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol __ARM_use_no_argv multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/tests/tests.o).
Error: L6200E: Symbol hydro_kdf_derive_from_key multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_n_1 multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kdf_keygen multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_pwhash_verify multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_pwhash_deterministic multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_secretbox_encrypt multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_sign_keygen multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_pad multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_xx_3 multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_hash_final multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_n_2 multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_sign_final_create multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_secretbox_keygen multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_secretbox_decrypt multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_xx_1 multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_random_buf_deterministic multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_kk_2 multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_random_reseed multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_secretbox_probe_verify multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_pwhash_keygen multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_init multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_random_ratchet multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_pwhash_create multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_sign_keygen_deterministic multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_xx_4 multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_xx_2 multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_hex2bin multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_memzero multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_hash_hash multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_bin2hex multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_keygen multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_sign_init multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_random_buf multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol main multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/tests/tests.o).
Error: L6200E: Symbol hydro_unpad multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_increment multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_random_uniform multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_sign_update multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_hash_update multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_pwhash_upgrade multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_kk_1 multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_equal multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_random_u32 multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_sign_final_verify multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_sign_create multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_pwhash_derive_static_key multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_compare multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_pwhash_reencrypt multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_keygen_deterministic multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_hash_keygen multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Not enough information to list the image map.
Finished: 1 information, 1 warning and 55 error messages.
[ERROR] Warning: L3912W: Option 'legacyalign' is deprecated.
Error: L6200E: Symbol hydro_sign_verify multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_kk_3 multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_hash_init multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_secretbox_probe_create multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol __ARM_use_no_argv multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/tests/tests.o).
Error: L6200E: Symbol hydro_kdf_derive_from_key multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_n_1 multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kdf_keygen multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_pwhash_verify multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_pwhash_deterministic multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_secretbox_encrypt multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_sign_keygen multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_pad multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_xx_3 multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_hash_final multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_n_2 multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_sign_final_create multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_secretbox_keygen multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_secretbox_decrypt multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_xx_1 multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_random_buf_deterministic multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_kk_2 multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_random_reseed multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_secretbox_probe_verify multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_pwhash_keygen multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_init multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_random_ratchet multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_pwhash_create multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_sign_keygen_deterministic multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_xx_4 multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_xx_2 multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_hex2bin multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_memzero multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_hash_hash multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_bin2hex multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_keygen multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_sign_init multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_random_buf multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol main multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/tests/tests.o).
Error: L6200E: Symbol hydro_unpad multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_increment multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_random_uniform multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_sign_update multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_hash_update multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_pwhash_upgrade multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_kk_1 multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_equal multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_random_u32 multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_sign_final_verify multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_sign_create multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_pwhash_derive_static_key multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_compare multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_pwhash_reencrypt multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_kx_keygen_deterministic multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Error: L6200E: Symbol hydro_hash_keygen multiply defined (by BUILD/NUCLEO_F429ZI/ARMC6/main.o and BUILD/NUCLEO_F429ZI/ARMC6/libhydrogen/hydrogen.o).
Not enough information to list the image map.
Finished: 1 information, 1 warning and 55 error messages.

Does anyone know what to do?

This is my code:

#include` "mbed.h"
#include "./../x86_example/hydrogen.cpp"

// main() runs in its own thread in the OS
int main()
{
    while (true) {
        //hydro_init();
    }
}

Code analysis

I just performed code analysis using PVS-Studio, and the application detected up to 19 warnings with various levels.

Here's a beautiful and convenient HTML report for you:
libhydrogen_analysis.zip

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.