Giter Site home page Giter Site logo

mlspp's Introduction

MLSPP CI

MLS++

Implementation of the proposed Messaging Layer Security protocol in C++. Depends on C++17, STL for data structures, and OpenSSL or BoringSSL for crypto.

Prerequisites

MLSPP requires a few prerequisite libraries in order to fully build.

  • nlohmann::json - Tested with latest versions.
  • Cryptography Library - OpenSSL 1.1.1, OpenSSL 3.0, BoringSSL compatible (see details below)
  • doctest - Tested with latest versions. Only required when building the test suite.

Installing Prerequisites

The following should satisfy the prerequisites for these popular platforms. However, vcpkg is recommended for developer builds.

# Linux - Ubuntu 20.04, Ubuntu 22.04
$ sudo apt install libssl-dev nlohmann-json3-dev doctest-dev

# MacOs - Homebrew
$ brew install nlohmann-json doctest

Quickstart

A convenience Makefile is included to avoid the need to remember a bunch of CMake parameters. It will use vcpkg to satisfy all dependencies.

> make        # Configures and builds the library 
> make dev    # Configure a "developer" build with tests and checks using OpenSSL 1.1
> make dev3   # Configure a "developer" build with tests and checks using OpenSSL 3.0
> make devB   # Configure a "developer" build with tests and checks using OpenSSL 3.0
> make test   # Builds and runs tests
> make format # Runs clang-format over the source

Conventions

  • Following Mozilla clang-format style. If you use the top-level Makefile (as suggested above), it will auto-format for you.
  • General naming conventions:
    • Camel case for classes (RatchetNode)
    • Snake case for variables, functions, members (derive_epoch_keys)
    • Private member variables start with underscore (_)
    • In general, prefer descriptive names

OpenSSL / BoringSSL

MLS++ requires OpenSSL of at least version 1.1.1, or BoringSSL compatible with the same requirement. MLS++ is compatible with OpenSSL >= 3.0.

Pass OPENSSL_ROOT_DIR to guide CMake to select a specific OpenSSL/BoringSSL installation. You may also need to specify OPENSSL_INCLUDE_DIR, OPENSSL_CRYPTO_LIBRARY, and OPENSSL_SSL_LIBRARY depending on the file and folder structure of your installation. When manually passing OPENSSL_* options one should carefully verify that both the includes and libraries match the expected installation.

mlspp's People

Contributors

bifurcation avatar birarda avatar ctjhai avatar czlitony avatar dependabot[bot] avatar dimarusyy avatar eiqo avatar fluffy avatar franziskuskiefer avatar glhewett avatar jidicula avatar kkohbrok avatar ojroques avatar pabuhler avatar razor-1 avatar suhashere avatar twal avatar

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

mlspp's Issues

Update CI to build the test harness

Right now, the cmd directory isn't built in the CI test builds, so we don't find out when those applications are broken. We have already had one instance of this, with #198 breaking the interop test client. We should extend the CI to also build the parts of cmd that still matter (in particular, the interop test harness), so that we detect these failures more quickly.

Fix interop client

#197 (and maybe others) have broken the interop client.

mls_client_impl.cpp:444:5: error: no matching
      constructor for initialization of 'mls::State'
    mls::State(join->init_priv, join->sig_priv, join->key_package, welcome);

mls_client_impl.cpp:466:61: error: too few arguments to
      function call, expected 5, have 4
    mls::State::external_join(leaf_secret, sig_priv, kp, pgs);

mls_client_impl.cpp:582:17: error: no matching member
      function for call to 'commit'
    entry.state.commit(leaf_secret, inline_proposals);

Re-enable session interop tests

Something in the work for draft-08 compatibility broke the session interop tests, so I disabled them for the moment. They should be re-enabled ASAP.

Eliminate RatchetType enum

The RatchetType enum in key_schedule.h is unnecessary. Callers should switch on ContentType; storage should just directly have handshake and application ratchets instead of an std::map<RatchetType, HashRatchet>.

Update to draft-12

From the change log in the draft (Degree of difficulty = Small / Medium / Large / Done. For "Done", just need to check that we are compliant.):

  • Add RequiredCapabilities extension (S)
  • Add group_context_extensions proposal ID (S)
  • Clarify extension handling and make extension updatable (M)
  • Clarify requirements around identity in MLS groups (M)
  • Constrain proposal in External Commit (M)
  • Don't require PublicGroupState for external init (S)
  • Improve extensibility of Proposals (S)
  • Inject GroupContext as HPKE info instead of AAD (S)
  • Make PreSharedKeys non optional in GroupSecrets (D)
  • Remove the notion of a 'leaf index' (L - Do together with "Use key package hash to index clients")
  • Signal the intended wire format for MLS messages (S)
  • Truncate tree size on removal (D)
  • Use HPKE draft-08 (D)
  • Use cascaded KDF instead of concatenation to consolidate PSKs (L - No PSK support at all right now)
  • Use key package hash to index clients in message structs (L)
  • Use the GroupContext to derive the joiner_secret (M)

Allow application to specify encryption padding

Right now, we allow padding to be specified in MLSPlaintext::marshal_content, but always set it to zero in GroupKeySource::encrypt. We should allow the application to specify padding when encryption is done. We could do this a few ways:

  1. Number of bytes of padding to add
  2. Size of the encoded content to produce
  3. "Granularity" of encoded content (i.e., size always grows by granularity bytes)

Option (1) seems the most flexible, but its utility is undermined by the fact that the caller doesn't know the size of the other encoded data. Option (2) is more intent-focused, but you need to address the case when the length exceeds the specified value. Option (3) can do any size, but might be wasteful if you go over by just a little.

Support for draft-04

  • Application key schedule fixes
  • ECIES -> HPKE
  • Hash of WelcomeInfo in the Add
  • Version negotiation fields
  • Key separation within TreeKEM
  • Garbage Collection

State is not serializable

Hey,

I'm trying to persist the latest state of the group. However tls::marshal(state) fails as State is not serializable. For our use case in memory caching cannot be relied on. What's the suggested way to achieve this?

Any help would be appreciated.

Thanks

Is it production ready ?

Hi,
My team is considering to use MLS for group e2ee.
Could you please say if this implementation is stable ?
Is it used in production code ?

Thanks

Windows support

Trying to build mlspp on windows emits an error:

Copyright (C) Microsoft Corporation. All rights reserved.
Checking File Globs
Microsoft (R) C/C++ Optimizing Compiler Version 19.27.29112 for x64
bytes.cpp
Copyright (C) Microsoft Corporation. All rights reserved.
cl /c /I..\mlspp\lib\bytes\include /Zi /W4 /WX /diagnostics:column /Od /Ob0 /D WIN32 /D _WINDOWS /D "CMAKE_INTDIR="Debug"" /D _MBCS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /GR /std:c++17 /Fo"bytes.dir\Debug\" /Fd"bytes.dir\Debug\bytes.pdb" /Gd /TP /errorReport:queue
..\mlspp\lib\bytes\src\bytes.cpp
..\mlspp\lib\bytes\src\bytes.cpp(38,20): error C2220: the following warning is treated as an error
[..\mlspp\lib\bytes\bytes.vcxproj]
..\mlspp\lib\bytes\src\bytes.cpp(38,20): warning C4244: '=': conversion from 'long' to '_Ty', possible loss of data >[..\mlspp\lib\bytes\bytes.vcxproj]
with
[
_Ty=uint8_t
]

Move Commit signature under confirmation_tag

The confirmation tag is used by endpoints to verify that they have arrived at the same key schedule. Recent spec versions have moved to include the signature under the confirmation tag. This will just entail adapting the signing/verification logic so that the signature is included in the confirmed transcript hash.

This has already been prototyped in #118, specifically:
d37b537

Crypto Agility

It should be possible for a built stack to support multiple DH / signature operations, and switch between them at run-time, depending on the group being started / joined.

Support downgrade protection

Two halves to this:

  • Send the supported_versions and supported_ciphersuites extensions
  • When initializing a group, verify that the chosen version/suite is the highest supported

Refactor signed object constructors

Signed objects, especially GroupInfo and KeyPackage, are used in basically two ways:

  1. Instantiate => sign => serialize
  2. Deserialize => verify => instantiate

Given that, it seems like we be able should have two constructors for these objects:

  1. A "signing constructor" of the form Thing(fields..., sig_priv)
  2. A "verifying constructor" of the form Thing(const bytes&, verify_data...) (where verify_data would include things like a tree from which the public key would be taken for GroupInfo)

The type might still need to be default-constructible to facilitate deserialization. Or it might be possible to define tls::get<T>(tls::ostream&), and then do:

Thing::Thing(tls::istream& str)
  : field1(tls::get<FieldType1>(str))
  , field2(tls::get<FieldType2>(str))
  , ...
{
  // verify signature
}

That would be a bit more boilerplate than TLS_SERIALIZABLE, but might be worth it for a clearer API.

Support OpenSSL 3.0

Currently, the hpke crypto library abstractions call several functions that have been deprecated in OpenSSL 3.0. Since the GitHub Actions runners appear to have upgraded to OpenSSL 3.0, this means that CI is broken until we support it.

The functions we rely on fall in basically three categories:

  • EC_KEY_*
    • EC_KEY_free
    • EC_KEY_get0_group
    • EC_KEY_get0_private_key
    • EC_KEY_new_by_curve_name
    • EC_KEY_set_private_key
    • EC_KEY_set_public_key
    • EVP_PKEY_assign
    • EVP_PKEY_get0_EC_KEY
  • Serialization / deserialization
    • i2o_ECPublicKey
    • o2i_ECPublicKey
  • HMAC
    • HMAC_CTX_free
    • HMAC_CTX_new
    • HMAC_CTX_set_flags
    • HMAC_Final
    • HMAC_Init_ex
    • HMAC_Update

We should not switch over entirely to 3.0, since it's pretty new. So we will need CMake tooling to detect what version we have, set a #define configuration, and then have both 1.1 and 3.0 implementations.

Useful references:

Logging

As the MLS spec finalizes, we are about to be doing a bunch of interop testing with other implementations. To facilitate debugging inevitable interop problems, we should add logging of at least:

  • Serialized and deserialized messages
  • Inputs and outputs of crypto operations

This logging should be selectively enabled, e.g., using environment variables. Cf. MINT_LOG

Collapse secret trees into one secret tree

In the current specification, application and handshake keys are derived from the same secret tree. This needs to be reflected in the key schedule logic here. Fortunately, this will be a deleting and simplifying:

  • NoFSBaseKeySource can be deleted, and as a result the abstract BaseKeySource can go way.
  • That leaves only TreeBaseKeySource, which can probably then be inlined into GroupKeySource
  • Instead of KeyScheduleEpoch having two GroupKeySource members, it should just have one, and expose the two ratchets per leaf.

OpenSSL error UNSUPPORTED_ALGORITHM when using mlspp with gRPC

Hello,

I'm building a small client app using mlspp and gRPC to communicate with a remote gRPC server. However my app crashes with the following error when trying to generate a new private key:

terminate called after throwing an instance of 'std::runtime_error'
  what():  error:06000080:public key routines:OPENSSL_internal:UNSUPPORTED_ALGORITHM

I've managed to reproduce the error with the following minimal example:

testapp.cpp:

#include <grpcpp/create_channel.h>
#include <mls/crypto.h>

int main() {
  std::shared_ptr<grpc::ChannelInterface> chan = grpc::CreateChannel(
      "localhost:50051", grpc::InsecureChannelCredentials());

  auto sig_priv = mls::SignaturePrivateKey::generate(
      mls::CipherSuite::ID::X25519_AES128GCM_SHA256_Ed25519);
}

CmakeLists.txt:

cmake_minimum_required(VERSION 3.15)

project(testapp
  VERSION 0.1
  LANGUAGES CXX
)

set(CMAKE_CXX_STANDARD 17)

find_package(MLSPP REQUIRED)
find_package(OpenSSL 1.1 REQUIRED)
find_package(Protobuf REQUIRED)
find_package(gRPC REQUIRED)

add_executable("testapp" "${CMAKE_CURRENT_SOURCE_DIR}/testapp.cpp")
target_link_libraries("testapp" MLSPP::mlspp gRPC::grpc++)

And the corresponding backtrace (mlspp is compiled on master in debug mode):

(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffff77a7859 in __GI_abort () at abort.c:79
#2  0x00007ffff7b7c911 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00007ffff7b8838c in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x00007ffff7b883f7 in std::terminate() () from /lib/x86_64-linux-gnu/libstdc++.so.6
#5  0x00007ffff7b886a9 in __cxa_throw () from /lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x00005555555c2d11 in hpke::RawKeyGroup::deserialize_private (this=0x555555ee9880 <hpke::Group::get<(hpke::Group::ID)5>()::instance>, skm=std::vector of length 32, capacity 32 = {...})
    at /home/olivier/Documents/mlspp/lib/hpke/src/group.cpp:378
#7  0x00005555555c2747 in hpke::RawKeyGroup::derive_key_pair (this=0x555555ee9880 <hpke::Group::get<(hpke::Group::ID)5>()::instance>, suite_id=std::vector of length 0, capacity 0,
    ikm=std::vector of length 32, capacity 32 = {...}) at /home/olivier/Documents/mlspp/lib/hpke/src/group.cpp:331
#8  0x00005555555bff9e in hpke::EVPGroup::generate_key_pair (this=0x555555ee9880 <hpke::Group::get<(hpke::Group::ID)5>()::instance>) at /home/olivier/Documents/mlspp/lib/hpke/src/group.cpp:47
#9  0x00005555555b8f60 in hpke::GroupSignature::generate_key_pair (this=0x555555ee93d0 <hpke::Signature::get<(hpke::Signature::ID)3>()::instance>) at /home/olivier/Documents/mlspp/lib/hpke/src/signature.cpp:55
#10 0x000055555559f7cf in mls::SignaturePrivateKey::generate (suite=...) at /home/olivier/Documents/mlspp/src/crypto.cpp:322
#11 0x000055555559d224 in main () at /home/olivier/.tmp/mlspp/testapp.cpp:9

What is strange is that the error disappears when I remove this line:

std::shared_ptr<grpc::ChannelInterface> chan = grpc::CreateChannel(
      "localhost:50051", grpc::InsecureChannelCredentials());

it's only the combination of gRPC and MLSPP that makes the app crash. There must be some kind of internal conflicts somewhere but I've no clue where exactly.

unable to make developer build on Ubuntu 18.04.6 LTS

After cloning the repo, I was able to build with make (after installing OpenSSL).
I also installed doctest in order to do a developer build using 'make dev' since there is dependency on doctest for the tests. However I am getting cmake errors about finding doctest:

CMake Error at lib/bytes/test/CMakeLists.txt:14 (include):
include could not find requested file:

doctest

CMake Error at lib/bytes/test/CMakeLists.txt:16 (doctest_discover_tests):
Unknown CMake command "doctest_discover_tests".

Looks like cmake is unable to find doctest.

A solution for this could be
modify cmake configuration to enable finding doctest
OR
add instruction steps to README consisting of simple commands to run

Randomly broken MLSCiphertext

Running the interop test vectors sometimes the MLSCiphertext looks like this

 [4, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 1, 1c, ae, 5, dc, 8b, 5c, 4c, ...

which translates to

  • group id: [0, 1, 2, 3]
  • epoch: 0x0001020304050607
  • content_type: Application

The next element should be the authenticated data vector of length up to 2^32. But it's 1c, ae, 5, dc, 8b, 5c, 4c, ..., which can't be correct. This looks like maybe the length header is missing.
Note that other times this looks correct, e.g. [0, 0, 0, 4, 1, 2, 3, 4, 1C, DE, 32, ....

Enable Proposal / Commit encryption

To first order, this just means filling in some arms of a couple of switch statements. The interesting part will be that Proposal / Commit messages will need more than a single key per sender. Current thinking in the working group is that intra-epoch FS isn't important for handshake keys, so we can use a one-step KDF instead of a tree.

Include errors under OpenSUSE 15.2 (Clang 11.0.0 RC2)

Hi.
I was trying to build in the following way:

../build/$cmake -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_FLAGS=' -stdlib=libc++ ' ..
-- The CXX compiler identification is Clang 11.0.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/clang++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenSSL: /usr/lib/x86_64-linux-gnu/libcrypto.so (found suitable version "2.0.0", minimum required is "1.1")
-- Configuring done
-- Generating done
-- Build files have been written to: /home/oceanfish81/mlspp/build

Here is what I got, during execution of

$make -j 4 --trace
:

Makefile:578: target 'cmake_check_build_system' does not exist
/usr/bin/cmake -P /home/oceanfish81/mlspp/build/CMakeFiles/VerifyGlobs.cmake
/usr/bin/cmake -S/home/oceanfish81/mlspp -B/home/oceanfish81/mlspp/build --check-build-system CMakeFiles/Makefile.cmake 0
Makefile:102: update target 'all' due to: cmake_check_build_system
/usr/bin/cmake -E cmake_progress_start /home/oceanfish81/mlspp/build/CMakeFiles /home/oceanfish81/mlspp/build//CMakeFiles/progress.marks
make -s -f CMakeFiles/Makefile2 all
CMakeFiles/Makefile2:406: target 'lib/tls_syntax/CMakeFiles/tls_syntax.dir/all' does not exist
make -s -f lib/tls_syntax/CMakeFiles/tls_syntax.dir/build.make lib/tls_syntax/CMakeFiles/tls_syntax.dir/depend
CMakeFiles/Makefile2:324: target 'lib/bytes/CMakeFiles/bytes.dir/all' does not exist
make -s -f lib/bytes/CMakeFiles/bytes.dir/build.make lib/bytes/CMakeFiles/bytes.dir/depend
lib/tls_syntax/CMakeFiles/tls_syntax.dir/build.make:116: target 'lib/tls_syntax/CMakeFiles/tls_syntax.dir/depend' does not exist
cd /home/oceanfish81/mlspp/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/oceanfish81/mlspp /home/oceanfish81/mlspp/lib/tls_syntax /home/oceanfish81/mlspp/build /home/oceanfish81/mlspp/build/lib/tls_syntax /home/oceanfish81/mlspp/build/lib/tls_syntax/CMakeFiles/tls_syntax.dir/DependInfo.cmake --color=
lib/bytes/CMakeFiles/bytes.dir/build.make:116: target 'lib/bytes/CMakeFiles/bytes.dir/depend' does not exist
cd /home/oceanfish81/mlspp/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/oceanfish81/mlspp /home/oceanfish81/mlspp/lib/bytes /home/oceanfish81/mlspp/build /home/oceanfish81/mlspp/build/lib/bytes /home/oceanfish81/mlspp/build/lib/bytes/CMakeFiles/bytes.dir/DependInfo.cmake --color=
make -s -f lib/tls_syntax/CMakeFiles/tls_syntax.dir/build.make lib/tls_syntax/CMakeFiles/tls_syntax.dir/build
make -s -f lib/bytes/CMakeFiles/bytes.dir/build.make lib/bytes/CMakeFiles/bytes.dir/build
/usr/bin/cmake -E cmake_echo_color --switch= --progress-dir=/home/oceanfish81/mlspp/build/CMakeFiles --progress-num=51,52 "Built target tls_syntax"
/usr/bin/cmake -E cmake_echo_color --switch= --progress-dir=/home/oceanfish81/mlspp/build/CMakeFiles --progress-num=3,4 "Built target bytes"
[ 5%] Built target tls_syntax
[ 7%] Built target bytes
CMakeFiles/Makefile2:351: update target 'lib/hpke/CMakeFiles/hpke.dir/all' due to: lib/bytes/CMakeFiles/bytes.dir/all
make -s -f lib/hpke/CMakeFiles/hpke.dir/build.make lib/hpke/CMakeFiles/hpke.dir/depend
CMakeFiles/Makefile2:434: update target 'lib/tls_syntax/test/CMakeFiles/tls_syntax_test.dir/all' due to: lib/tls_syntax/CMakeFiles/tls_syntax.dir/all lib/bytes/CMakeFiles/bytes.dir/all
make -s -f lib/tls_syntax/test/CMakeFiles/tls_syntax_test.dir/build.make lib/tls_syntax/test/CMakeFiles/tls_syntax_test.dir/depend
lib/hpke/CMakeFiles/hpke.dir/build.make:251: target 'lib/hpke/CMakeFiles/hpke.dir/depend' does not exist
cd /home/oceanfish81/mlspp/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/oceanfish81/mlspp /home/oceanfish81/mlspp/lib/hpke /home/oceanfish81/mlspp/build /home/oceanfish81/mlspp/build/lib/hpke /home/oceanfish81/mlspp/build/lib/hpke/CMakeFiles/hpke.dir/DependInfo.cmake --color=
lib/tls_syntax/test/CMakeFiles/tls_syntax_test.dir/build.make:133: target 'lib/tls_syntax/test/CMakeFiles/tls_syntax_test.dir/depend' does not exist
cd /home/oceanfish81/mlspp/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/oceanfish81/mlspp /home/oceanfish81/mlspp/lib/tls_syntax/test /home/oceanfish81/mlspp/build /home/oceanfish81/mlspp/build/lib/tls_syntax/test /home/oceanfish81/mlspp/build/lib/tls_syntax/test/CMakeFiles/tls_syntax_test.dir/DependInfo.cmake --color=
make -s -f lib/hpke/CMakeFiles/hpke.dir/build.make lib/hpke/CMakeFiles/hpke.dir/build
make -s -f lib/tls_syntax/test/CMakeFiles/tls_syntax_test.dir/build.make lib/tls_syntax/test/CMakeFiles/tls_syntax_test.dir/build
lib/hpke/CMakeFiles/hpke.dir/build.make:81: update target 'lib/hpke/CMakeFiles/hpke.dir/src/aead_cipher.cpp.o' due to: ../lib/hpke/src/aead_cipher.cpp ../lib/bytes/include/bytes/bytes.h ../lib/hpke/include/hpke/hpke.h ../lib/hpke/src/aead_cipher.h ../lib/hpke/src/openssl_common.h lib/hpke/CMakeFiles/hpke.dir/flags.make
/usr/bin/cmake -E cmake_echo_color --switch= --green --progress-dir=/home/oceanfish81/mlspp/build/CMakeFiles --progress-num=5 "Building CXX object lib/hpke/CMakeFiles/hpke.dir/src/aead_cipher.cpp.o"
lib/hpke/CMakeFiles/hpke.dir/build.make:133: update target 'lib/hpke/CMakeFiles/hpke.dir/src/group.cpp.o' due to: ../lib/hpke/src/group.cpp ../lib/bytes/include/bytes/bytes.h ../lib/hpke/include/hpke/hpke.h ../lib/hpke/include/hpke/random.h ../lib/hpke/include/hpke/signature.h ../lib/hpke/src/common.h ../lib/hpke/src/group.h ../lib/hpke/src/openssl_common.h lib/hpke/CMakeFiles/hpke.dir/flags.make
/usr/bin/cmake -E cmake_echo_color --switch= --green --progress-dir=/home/oceanfish81/mlspp/build/CMakeFiles --progress-num=9 "Building CXX object lib/hpke/CMakeFiles/hpke.dir/src/group.cpp.o"
/usr/bin/cmake -E cmake_echo_color --switch= --progress-dir=/home/oceanfish81/mlspp/build/CMakeFiles --progress-num=53,54,55 "Built target tls_syntax_test"
lib/hpke/CMakeFiles/hpke.dir/build.make:159: update target 'lib/hpke/CMakeFiles/hpke.dir/src/hpke.cpp.o' due to: ../lib/hpke/src/hpke.cpp ../lib/bytes/include/bytes/bytes.h ../lib/hpke/include/hpke/digest.h ../lib/hpke/include/hpke/hpke.h ../lib/hpke/include/hpke/signature.h ../lib/hpke/src/aead_cipher.h ../lib/hpke/src/common.h ../lib/hpke/src/dhkem.h ../lib/hpke/src/group.h ../lib/hpke/src/hkdf.h lib/hpke/CMakeFiles/hpke.dir/flags.make
/usr/bin/cmake -E cmake_echo_color --switch= --green --progress-dir=/home/oceanfish81/mlspp/build/CMakeFiles --progress-num=11 "Building CXX object lib/hpke/CMakeFiles/hpke.dir/src/hpke.cpp.o"
[ 9%] Building CXX object lib/hpke/CMakeFiles/hpke.dir/src/aead_cipher.cpp.o
[ 10%] Building CXX object lib/hpke/CMakeFiles/hpke.dir/src/group.cpp.o
cd /home/oceanfish81/mlspp/build/lib/hpke && /usr/bin/clang++ -I/home/oceanfish81/mlspp/lib/hpke/include -I/home/oceanfish81/mlspp/lib/bytes/include -stdlib=libc++ -Wall -pedantic -Wextra -Werror -std=gnu++17 -o CMakeFiles/hpke.dir/src/aead_cipher.cpp.o -c /home/oceanfish81/mlspp/lib/hpke/src/aead_cipher.cpp
[ 18%] Building CXX object lib/hpke/CMakeFiles/hpke.dir/src/hpke.cpp.o
[ 18%] Built target tls_syntax_test
cd /home/oceanfish81/mlspp/build/lib/hpke && /usr/bin/clang++ -I/home/oceanfish81/mlspp/lib/hpke/include -I/home/oceanfish81/mlspp/lib/bytes/include -stdlib=libc++ -Wall -pedantic -Wextra -Werror -std=gnu++17 -o CMakeFiles/hpke.dir/src/group.cpp.o -c /home/oceanfish81/mlspp/lib/hpke/src/group.cpp
cd /home/oceanfish81/mlspp/build/lib/hpke && /usr/bin/clang++ -I/home/oceanfish81/mlspp/lib/hpke/include -I/home/oceanfish81/mlspp/lib/bytes/include -stdlib=libc++ -Wall -pedantic -Wextra -Werror -std=gnu++17 -o CMakeFiles/hpke.dir/src/hpke.cpp.o -c /home/oceanfish81/mlspp/lib/hpke/src/hpke.cpp
lib/hpke/CMakeFiles/hpke.dir/build.make:172: update target 'lib/hpke/CMakeFiles/hpke.dir/src/openssl_common.cpp.o' due to: ../lib/hpke/src/openssl_common.cpp ../lib/bytes/include/bytes/bytes.h ../lib/hpke/include/hpke/hpke.h ../lib/hpke/src/openssl_common.h lib/hpke/CMakeFiles/hpke.dir/flags.make
/usr/bin/cmake -E cmake_echo_color --switch= --green --progress-dir=/home/oceanfish81/mlspp/build/CMakeFiles --progress-num=12 "Building CXX object lib/hpke/CMakeFiles/hpke.dir/src/openssl_common.cpp.o"
[ 20%] Building CXX object lib/hpke/CMakeFiles/hpke.dir/src/openssl_common.cpp.o
cd /home/oceanfish81/mlspp/build/lib/hpke && /usr/bin/clang++ -I/home/oceanfish81/mlspp/lib/hpke/include -I/home/oceanfish81/mlspp/lib/bytes/include -stdlib=libc++ -Wall -pedantic -Wextra -Werror -std=gnu++17 -o CMakeFiles/hpke.dir/src/openssl_common.cpp.o -c /home/oceanfish81/mlspp/lib/hpke/src/openssl_common.cpp
/home/oceanfish81/mlspp/lib/hpke/src/aead_cipher.cpp:102:14: error: use of undeclared identifier 'EVP_chacha20_poly1305'; did you mean 'EVP_aead_chacha20_poly1305'?
return EVP_chacha20_poly1305();
^~~~~~~~~~~~~~~~~~~~~
EVP_aead_chacha20_poly1305
/usr/local/include/openssl/evp.h:1273:17: note: 'EVP_aead_chacha20_poly1305' declared here
const EVP_AEAD *EVP_aead_chacha20_poly1305(void);
^
/home/oceanfish81/mlspp/lib/hpke/src/aead_cipher.cpp:102:14: error: cannot initialize return object of type 'const EVP_CIPHER *' (aka 'const evp_cipher_st *') with an rvalue of type 'const EVP_AEAD *' (aka 'const evp_aead_st *')
return EVP_chacha20_poly1305();
^~~~~~~~~~~~~~~~~~~~~~~
/home/oceanfish81/mlspp/lib/hpke/src/group.cpp:119:14: error: use of undeclared identifier 'EVP_DigestSign'; did you mean 'EVP_DigestSignInit'?
if (1 != EVP_DigestSign(
^~~~~~~~~~~~~~
EVP_DigestSignInit
/usr/local/include/openssl/evp.h:627:5: note: 'EVP_DigestSignInit' declared here
int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
^
/home/oceanfish81/mlspp/lib/hpke/src/group.cpp:120:27: error: cannot initialize a parameter of type 'EVP_PKEY_CTX **' (aka 'evp_pkey_ctx_st **') with an rvalue of type 'std::__1::vector<unsigned char, std::__1::allocator>::value_type *' (aka 'unsigned char *')
ctx.get(), sig.data(), &siglen, data.data(), data.size())) {
^~~~~~~~~~
/usr/local/include/openssl/evp.h:627:56: note: passing argument to parameter 'pctx' here
int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
^
/home/oceanfish81/mlspp/lib/hpke/src/group.cpp:144:15: error: use of undeclared identifier 'EVP_DigestVerify'; did you mean 'EVP_DigestVerifyInit'?
auto rv = EVP_DigestVerify(
^~~~~~~~~~~~~~~~
EVP_DigestVerifyInit
/usr/local/include/openssl/evp.h:631:5: note: 'EVP_DigestVerifyInit' declared here
int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
^
/home/oceanfish81/mlspp/lib/hpke/src/group.cpp:145:18: error: cannot initialize a parameter of type 'EVP_PKEY_CTX **' (aka 'evp_pkey_ctx_st **') with an rvalue of type 'const std::__1::vector<unsigned char, std::__1::allocator>::value_type *' (aka 'const unsigned char *')
ctx.get(), sig.data(), sig.size(), data.data(), data.size());
^~~~~~~~~~
/usr/local/include/openssl/evp.h:631:58: note: passing argument to parameter 'pctx' here
int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
^
2 errors generated.
/home/oceanfish81/mlspp/lib/hpke/src/group.cpp:359:14: error: use of undeclared identifier 'EVP_PKEY_get_raw_public_key'
if (1 != EVP_PKEY_get_raw_public_key(rpk.pkey.get(), data_ptr, &data_len)) {
^
make[2]: *** [lib/hpke/CMakeFiles/hpke.dir/build.make:82: lib/hpke/CMakeFiles/hpke.dir/src/aead_cipher.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
/home/oceanfish81/mlspp/lib/hpke/src/group.cpp:369:7: error: use of undeclared identifier 'EVP_PKEY_new_raw_public_key'; did you mean 'EVP_PKEY_new_mac_key'?
EVP_PKEY_new_raw_public_key(evp_type, nullptr, enc.data(), enc.size());
^~~~~~~~~~~~~~~~~~~~~~~~~~~
EVP_PKEY_new_mac_key
/usr/local/include/openssl/evp.h:1150:11: note: 'EVP_PKEY_new_mac_key' declared here
EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, const unsigned char *key,
^
/home/oceanfish81/mlspp/lib/hpke/src/group.cpp:384:9: error: use of undeclared identifier 'EVP_PKEY_get_raw_private_key'
EVP_PKEY_get_raw_private_key(rsk.pkey.get(), data_ptr, &data_len)) {
^
/home/oceanfish81/mlspp/lib/hpke/src/group.cpp:395:7: error: use of undeclared identifier 'EVP_PKEY_new_raw_private_key'
EVP_PKEY_new_raw_private_key(evp_type, nullptr, skm.data(), skm.size());
^
/home/oceanfish81/mlspp/lib/hpke/src/group.cpp:410:16: error: use of undeclared identifier 'EVP_PKEY_X25519'
return EVP_PKEY_X25519;
^
/home/oceanfish81/mlspp/lib/hpke/src/group.cpp:412:16: error: use of undeclared identifier 'EVP_PKEY_X448'
return EVP_PKEY_X448;
^
/home/oceanfish81/mlspp/lib/hpke/src/group.cpp:414:16: error: use of undeclared identifier 'EVP_PKEY_ED25519'
return EVP_PKEY_ED25519;
^
/home/oceanfish81/mlspp/lib/hpke/src/group.cpp:416:16: error: use of undeclared identifier 'EVP_PKEY_ED448'
return EVP_PKEY_ED448;
^
12 errors generated.
make[2]: *** [lib/hpke/CMakeFiles/hpke.dir/build.make:134: lib/hpke/CMakeFiles/hpke.dir/src/group.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:352: lib/hpke/CMakeFiles/hpke.dir/all] Error 2
make: *** [Makefile:103: all] Error 2

$ clang --version
clang version 11.0.0 (https://github.com/llvm/llvm-project.git 0160ad802e899c2922bc9b29564080c22eb0908c)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

$ cmake --version
cmake version 3.18.2

I was trying to build using/link against libc++ .

CC @pabuhler @bifurcation @fluffy

Ivan

Support inline proposals

Recent spec changes allowed for proposal to be included in a Commit. The main change here is that instead of only having proposals by reference, they can be provided by reference or by value; there's still just one array of proposals in a commit that determines the order of their application.

This has been prototyped out in #118, specifically:
a52018c

Cannot find doctest

Hello,

I'm on Ubuntu 18.04, I do have the required dependencies installed yet I cannot build the project following the README instructions. I get this error:

cmake -Bbuild -DCMAKE_BUILD_TYPE=Debug .
-- The CXX compiler identification is GNU 7.5.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Error at lib/bytes/test/CMakeLists.txt:4 (find_package):
  By not providing "Finddoctest.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "doctest", but
  CMake did not find one.

  Could not find a package configuration file provided by "doctest" with any
  of the following names:

    doctestConfig.cmake
    doctest-config.cmake

  Add the installation prefix of "doctest" to CMAKE_PREFIX_PATH or set
  "doctest_DIR" to a directory containing one of the above files.  If
  "doctest" provides a separate development package or SDK, be sure it has
  been installed.


-- Configuring incomplete, errors occurred!
See also "/home/olivier/Documents/mlspp/build/CMakeFiles/CMakeOutput.log".
Makefile:17: recipe for target 'build' failed
make: *** [build] Error 1

I've tried installing doctest myself but simply placing doctest.h in the root folder or in include/doctest/ or in any other place does not work. So is there a way to build the project without having to write a Finddoctest.cmake ourselves?

Pull out reusable components into their own targets

There are a few bits in here that might be useful to reuse elsewhere:

  • TLS syntax marshal/unmarshal
  • HPKE and possibly C++ abstraction over OpenSSL more generally

We should pull these out into separate targets to facilitate independent review / reuse.

Apply zeroization consistently

Currently, some secrets are zeroized in accordance with the MLS deletion schedule, but others are not, notably on the main MLS key schedule. We should zeroize more consistently. For example, we could create a Secret type that would wrap bytes and have a destructor that would zeroize the stored data before freeing it, then consistently use that type for values that require zeroization.

Unable to perform any operation on large groups

Hello,

2021-07-28 update: code updated for abcd2ee (main)

I'm trying to benchmark how mlspp performs with large groups. Unfortunately I cannot perform any group operation on groups with a number of members greater than 312. With such a group size, creating an Update proposal fails for instance. I tried debugging the error myself and located it but can't really see what more I can do. Is this something fixable or is it my use case that is not intended to be supported?

My setup:

  • mlspp commit: abcd2ee (main as of 2021-07-28)
  • Kernel version: 5.4.0-74-generic
  • OS: Ubuntu 20.04
  • OpenSSL version: OpenSSL 1.1.1f 31 Mar 2020

The code to reproduce the error:

#include "mls/session.h"

const mls::CipherSuite suite{
    mls::CipherSuite::ID::X25519_AES128GCM_SHA256_Ed25519};

static mls::Client create_client(mls::CipherSuite suite,
                                 const std::string &name) {
  auto id = bytes(name.begin(), name.end());
  auto sig_priv = mls::SignaturePrivateKey::generate(suite);
  auto cred = mls::Credential::basic(id, suite, sig_priv.public_key);
  return mls::Client(suite, sig_priv, cred, std::nullopt);
}

static std::vector<mls::Session> create_group(int N) {
  std::vector<mls::Session> sessions;

  // Initialize the member who creates the MLS group
  mls::Client leader = create_client(suite, "member0");

  // Initialize N-1 members
  std::vector<mls::PendingJoin> members;
  for (int i = 1; i < N; ++i) {
    mls::Client member = create_client(suite, "member" + std::to_string(i));
    members.push_back(member.start_join());
  }

  // Create group
  sessions.push_back(leader.begin_session({0, 1, 2, 3}));

  // Add members
  std::vector<bytes> add_proposals;
  for (const auto &member : members) {
    add_proposals.push_back(sessions[0].add(member.key_package()));
  }

  // Build commit and welcome messages
  auto [welcome, commit] = sessions[0].commit(add_proposals);

  // Update group state
  sessions[0].handle(commit);
  for (const auto &member : members) {
    sessions.push_back(member.complete(welcome));
  }

  return sessions;
}

int main() {
  std::vector<mls::Session> sessions = create_group(312);
  bytes update = sessions[0].update();
}

The error I get when size N is >=312:

terminate called after throwing an instance of 'tls::WriteError'
  what():  Data too large for header size
.buildme.sh: line 28: 145352 Aborted                 (core dumped) ./test

The backtrace:

(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffff7915859 in __GI_abort () at abort.c:79
#2  0x00007ffff7b9b951 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00007ffff7ba747c in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x00007ffff7ba74e7 in std::terminate() () from /lib/x86_64-linux-gnu/libstdc++.so.6
#5  0x00007ffff7ba7799 in __cxa_throw () from /lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x00005555555644ae in tls::vector<2ul, 18446744073709551615ul, 18446744073709551615ul>::encode<unsigned char> (str=..., data=std::vector of length 65615, capacity 65615 = {...})
    at /home/olivier/Documents/mlspp/lib/tls_syntax/include/tls/tls_syntax.h:329
#7  0x00005555555712fa in tls::write_tuple_traits<std::tuple<tls::pass, tls::vector<2ul, 18446744073709551615ul, 18446744073709551615ul> >, 1ul, unsigned short const&, std::vector<unsigned char, std::allocator<unsigned char> > const&> (str=..., t=std::tuple containing = {...})
    at /home/olivier/Documents/mlspp/lib/tls_syntax/include/tls/tls_syntax.h:498
#8  0x0000555555571264 in tls::write_tuple_traits<std::tuple<tls::pass, tls::vector<2ul, 18446744073709551615ul, 18446744073709551615ul> >, 0ul, unsigned short const&, std::vector<unsigned char, std::allocator<unsigned char> > const&> (str=..., t=std::tuple containing = {...})
    at /home/olivier/Documents/mlspp/lib/tls_syntax/include/tls/tls_syntax.h:499
#9  0x00005555555711d2 in tls::operator<< <mls::Extension> (str=..., obj=...)
    at /home/olivier/Documents/mlspp/lib/tls_syntax/include/tls/tls_syntax.h:508
#10 0x0000555555571014 in tls::vector<4ul, 18446744073709551615ul, 18446744073709551615ul>::encode<mls::Extension> (str=..., data=std::vector of length 1, capacity 1 = {...})
    at /home/olivier/Documents/mlspp/lib/tls_syntax/include/tls/tls_syntax.h:323
#11 0x0000555555570ed4 in tls::write_tuple_traits<std::tuple<tls::vector<4ul, 18446744073709551615ul, 18446744073709551615ul> >, 0ul, std::vector<mls::Extension, std::allocator<mls::Extension> > const&> (
    str=..., t=std::tuple containing = {...})
    at /home/olivier/Documents/mlspp/lib/tls_syntax/include/tls/tls_syntax.h:498
#12 0x0000555555570da1 in tls::operator<< <mls::ExtensionList> (str=..., obj=...)
    at /home/olivier/Documents/mlspp/lib/tls_syntax/include/tls/tls_syntax.h:508
#13 0x00005555555709fc in tls::pass::encode<mls::ExtensionList> (str=..., val=...)
    at /home/olivier/Documents/mlspp/lib/tls_syntax/include/tls/tls_syntax.h:277
#14 0x00005555556004f2 in tls::write_tuple_traits<std::tuple<tls::vector<1ul, 18446744073709551615ul, 18446744073709551615ul>, tls::pass, tls::vector<1ul, 18446744073709551615ul, 18446744073709551615ul>, tls::vector<1ul, 18446744073709551615ul, 18446744073709551615ul>, tls::pass, tls::pass, tls::pass, tls::vector<2ul, 18446744073709551615ul, 18446744073709551615ul> >, 4ul, std::vector<unsigned char, std::allocator<unsigned char> > const&, unsigned long const&, std::vector<unsigned char, std::allocator<unsigned char> > const&, std::vector<unsigned char, std::allocator<unsigned char> > const&, mls::ExtensionList const&, mls::MAC const&, mls::LeafIndex const&, std::vector<unsigned char, std::allocator<unsigned char> > const&> (str=..., t=std::tuple containing = {...})
    at /home/olivier/Documents/mlspp/lib/tls_syntax/include/tls/tls_syntax.h:498
#15 0x000055555560017c in tls::write_tuple_traits<std::tuple<tls::vector<1ul, 18446744073709551615ul, 18446744073709551615ul>, tls::pass, tls::vector<1ul, 18446744073709551615ul, 18446744073709551615ul>, tls::vector<1ul, 18446744073709551615ul, 18446744073709551615ul>, tls::pass, tls::pass, tls::pass, tls::vector<2ul, 18446744073709551615ul, 18446744073709551615ul> >, 3ul, std::vector<unsigned char, std::allocator<unsigned char> > const&, unsigned long const&, std::vector<unsigned char, std::allocator<unsigned char> > const&, std::vector<unsigned char, std::allocator<unsigned char> > const&, mls::ExtensionList const&, mls::MAC const&, mls::LeafIndex const&, std::vector<unsigned char, std::allocator<unsigned char> > const&> (str=..., t=std::tuple containing = {...})
    at /home/olivier/Documents/mlspp/lib/tls_syntax/include/tls/tls_syntax.h:499
#16 0x00005555555ffe45 in tls::write_tuple_traits<std::tuple<tls::vector<1ul, 18446744073709551615ul, 18446744073709551615ul>, tls::pass, tls::vector<1ul, 18446744073709551615ul, 18446744073709551615ul>, tls::vector<1ul, 18446744073709551615ul, 18446744073709551615ul>, tls::pass, tls::pass, tls::pass, tls::vector<2ul, 18446744073709551615ul, 18446744073709551615ul> >, 2ul, std::vector<unsigned char, std::allocator<unsigned char> > const&, unsigned long const&, std::vector<unsigned char, std::allocator<unsigned char> > const&, std::vector<unsigned char, std::allocator<unsigned char> > const&, mls::ExtensionList --Type <R--Type <RET> for more, q to quit, c to continue without paging--
const&, mls::MAC const&, mls::LeafIndex const&, std::vector<unsigned char, std::allocator<unsigned char> > const&> (str=..., t=std::tuple containing = {...})
    at /home/olivier/Documents/mlspp/lib/tls_syntax/include/tls/tls_syntax.h:499
#17 0x00005555555ffae4 in tls::write_tuple_traits<std::tuple<tls::vector<1ul, 18446744073709551615ul, 18446744073709551615ul>, tls::pass, tls::vector<1ul, 18446744073709551615ul, 18446744073709551615ul>, tls::vector<1ul, 18446744073709551615ul, 18446744073709551615ul>, tls::pass, tls::pass, tls::pass, tls::vector<2ul, 18446744073709551615ul, 18446744073709551615ul> >, 1ul, std::vector<unsigned char, std::allocator<unsigned char> > const&, unsigned long const&, std::vector<unsigned char, std::allocator<unsigned char> > const&, std::vector<unsigned char, std::allocator<unsigned char> > const&, mls::ExtensionList const&, mls::MAC const&, mls::LeafIndex const&, std::vector<unsigned char, std::allocator<unsigned char> > const&> (str=..., t=std::tuple containing = {...})
    at /home/olivier/Documents/mlspp/lib/tls_syntax/include/tls/tls_syntax.h:499
#18 0x00005555555ff074 in tls::write_tuple_traits<std::tuple<tls::vector<1ul, 18446744073709551615ul, 18446744073709551615ul>, tls::pass, tls::vector<1ul, 18446744073709551615ul, 18446744073709551615ul>, tls::vector<1ul, 18446744073709551615ul, 18446744073709551615ul>, tls::pass, tls::pass, tls::pass, tls::vector<2ul, 18446744073709551615ul, 18446744073709551615ul> >, 0ul, std::vector<unsigned char, std::allocator<unsigned char> > const&, unsigned long const&, std::vector<unsigned char, std::allocator<unsigned char> > const&, std::vector<unsigned char, std::allocator<unsigned char> > const&, mls::ExtensionList const&, mls::MAC const&, mls::LeafIndex const&, std::vector<unsigned char, std::allocator<unsigned char> > const&> (str=..., t=std::tuple containing = {...})
    at /home/olivier/Documents/mlspp/lib/tls_syntax/include/tls/tls_syntax.h:499
#19 0x00005555555fe544 in tls::operator<< <mls::GroupInfo> (str=..., obj=...) at /home/olivier/Documents/mlspp/lib/tls_syntax/include/tls/tls_syntax.h:508
#20 0x00005555555fd3c4 in tls::marshal<mls::GroupInfo> (value=...) at /home/olivier/Documents/mlspp/lib/tls_syntax/include/tls/tls_syntax.h:199
#21 0x00005555555fa9e7 in mls::Welcome::Welcome (this=0x7fffffffcd40, suite=..., joiner_secret=std::vector of length 32, capacity 32 = {...}, psk_secret=std::vector of length 0, capacity 0, group_info=...)
    at /home/olivier/Documents/mlspp/src/messages.cpp:163
#22 0x00005555555ba6ac in mls::State::commit (this=0x5555556f72b0, leaf_secret=std::vector of length 32, capacity 32 = {...}, opts=std::optional<struct mls::CommitOpts> = {...},
    joiner_key_package=std::optional<struct mls::KeyPackage> [no contained value], external_pub=std::optional<struct mls::HPKEPublicKey> [no contained value])
    at /home/olivier/Documents/mlspp/src/state.cpp:399
#23 0x00005555555b9901 in mls::State::commit (this=0x5555556f72b0, leaf_secret=std::vector of length 32, capacity 32 = {...}, opts=std::optional<struct mls::CommitOpts> = {...})
    at /home/olivier/Documents/mlspp/src/state.cpp:277
#24 0x000055555557e109 in mls::Session::commit (this=0x5555556f6300) at /home/olivier/Documents/mlspp/src/session.cpp:290
#25 0x000055555557dfca in mls::Session::commit (this=0x5555556f6300, proposals=std::vector of length 311, capacity 512 = {...}) at /home/olivier/Documents/mlspp/src/session.cpp:282
#26 0x000055555555e11c in create_group (N=312) at /home/olivier/Documents/mls-benchmark/src/test.cpp:40
#27 0x000055555555e46f in main () at /home/olivier/Documents/mls-benchmark/src/test.cpp:52

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.