Skip to content

Commit

Permalink
Merge pull request #75 from mpretty-cyro/general-encryption
Browse files Browse the repository at this point in the history
General encryption
  • Loading branch information
jagerman authored Jan 25, 2024
2 parents c6ec3fe + c7b7dea commit 343cd41
Show file tree
Hide file tree
Showing 42 changed files with 3,702 additions and 135 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/build*/
/compile_commands.json
/.cache/
/.vscode/
116 changes: 116 additions & 0 deletions include/session/blinding.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#pragma once

#ifdef __cplusplus
extern "C" {
#endif

#include <stddef.h>

#include "export.h"

/// API: crypto/session_blind15_key_pair
///
/// This function attempts to generate a blind15 key pair.
///
/// Inputs:
/// - `ed25519_seckey` -- [in] the Ed25519 private key of the sender (64 bytes).
/// - `server_pk` -- [in] the public key of the open group server to generate the
/// blinded id for (32 bytes).
/// - `blinded_pk_out` -- [out] pointer to a buffer of at least 32 bytes where the blinded_pk will
/// be written if generation was successful.
/// - `blinded_sk_out` -- [out] pointer to a buffer of at least 32 bytes where the blinded_sk will
/// be written if generation was successful.
///
/// Outputs:
/// - `bool` -- True if the key was successfully generated, false if generation failed.
LIBSESSION_EXPORT bool session_blind15_key_pair(
const unsigned char* ed25519_seckey, /* 64 bytes */
const unsigned char* server_pk, /* 32 bytes */
unsigned char* blinded_pk_out, /* 32 byte output buffer */
unsigned char* blinded_sk_out /* 32 byte output buffer */);

/// API: crypto/session_blind25_key_pair
///
/// This function attempts to generate a blind25 key pair.
///
/// Inputs:
/// - `ed25519_seckey` -- [in] the Ed25519 private key of the sender (64 bytes).
/// - `server_pk` -- [in] the public key of the open group server to generate the
/// blinded id for (32 bytes).
/// - `blinded_pk_out` -- [out] pointer to a buffer of at least 32 bytes where the blinded_pk will
/// be written if generation was successful.
/// - `blinded_sk_out` -- [out] pointer to a buffer of at least 32 bytes where the blinded_sk will
/// be written if generation was successful.
///
/// Outputs:
/// - `bool` -- True if the key was successfully generated, false if generation failed.
LIBSESSION_EXPORT bool session_blind25_key_pair(
const unsigned char* ed25519_seckey, /* 64 bytes */
const unsigned char* server_pk, /* 32 bytes */
unsigned char* blinded_pk_out, /* 32 byte output buffer */
unsigned char* blinded_sk_out /* 32 byte output buffer */);

/// API: crypto/session_blind15_sign
///
/// This function attempts to generate a signature for a message using a blind15 private key.
///
/// Inputs:
/// - `ed25519_seckey` -- [in] the Ed25519 private key of the sender (64 bytes).
/// - `server_pk` -- [in] the public key of the open group server to generate the
/// blinded id for (32 bytes).
/// - `msg` -- [in] Pointer to a data buffer containing the message to generate a signature for.
/// - `msg_len` -- [in] Length of `msg`
/// - `blinded_sig_out` -- [out] pointer to a buffer of at least 64 bytes where the signature will
/// be written if generation was successful.
///
/// Outputs:
/// - `bool` -- True if the signature was successfully generated, false if generation failed.
LIBSESSION_EXPORT bool session_blind15_sign(
const unsigned char* ed25519_seckey, /* 64 bytes */
const unsigned char* server_pk, /* 32 bytes */
const unsigned char* msg,
size_t msg_len,
unsigned char* blinded_sig_out /* 64 byte output buffer */);

/// API: crypto/session_blind25_sign
///
/// This function attempts to generate a signature for a message using a blind25 private key.
///
/// Inputs:
/// - `ed25519_seckey` -- [in] the Ed25519 private key of the sender (64 bytes).
/// - `server_pk` -- [in] the public key of the open group server to generate the
/// blinded id for (32 bytes).
/// - `msg` -- [in] Pointer to a data buffer containing the message to generate a signature for.
/// - `msg_len` -- [in] Length of `msg`
/// - `blinded_sig_out` -- [out] pointer to a buffer of at least 64 bytes where the signature will
/// be written if generation was successful.
///
/// Outputs:
/// - `bool` -- True if the signature was successfully generated, false if generation failed.
LIBSESSION_EXPORT bool session_blind25_sign(
const unsigned char* ed25519_seckey, /* 64 bytes */
const unsigned char* server_pk, /* 32 bytes */
const unsigned char* msg,
size_t msg_len,
unsigned char* blinded_sig_out /* 64 byte output buffer */);

/// API: crypto/session_blind25_sign
///
/// This function attempts to generate a signature for a message using a blind25 private key.
///
/// Inputs:
/// - `session_id` -- [in] the session_id to compare (66 bytes with a 05 prefix).
/// - `blinded_id` -- [in] the blinded_id to compare, can be either 15 or 25 blinded (66 bytes).
/// - `server_pk` -- [in] the public key of the open group server to the blinded id came from (64
/// bytes).
///
/// Outputs:
/// - `bool` -- True if the session_id matches the blinded_id, false if not.
LIBSESSION_EXPORT bool session_id_matches_blinded_id(
const char* session_id, /* 66 bytes */
const char* blinded_id, /* 66 bytes */
const char* server_pk /* 64 bytes */);

#ifdef __cplusplus
}
#endif
94 changes: 91 additions & 3 deletions include/session/blinding.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,25 @@ namespace session {
///
/// This (R, S) signature is then Ed25519-verifiable using pubkey kA.

/// Returns the blinding factor for 15 blinding. Typically this isn't used directly, but is
/// exposed for debugging/testing. Takes server pk in bytes, not hex.
uc32 blind15_factor(ustring_view server_pk);

/// Returns the blinding factor for 25 blinding. Typically this isn't used directly, but is
/// exposed for debugging/testing. Takes session id and pk in bytes, not hex. session id can
/// be 05-prefixed (33 bytes) or unprefixed (32 bytes).
std::array<unsigned char, 32> blind25_factor(ustring_view session_id, ustring_view server_pk);
/// exposed for debugging/testing. Takes session id and server pk in bytes, not hex. session
/// id can be 05-prefixed (33 bytes) or unprefixed (32 bytes).
uc32 blind25_factor(ustring_view session_id, ustring_view server_pk);

/// Computes the two possible 15-blinded ids from a session id and server pubkey. Values accepted
/// and returned are hex-encoded.
std::array<std::string, 2> blind15_id(std::string_view session_id, std::string_view server_pk);

/// Similar to the above, but takes the session id and pubkey as byte values instead of hex, and
/// returns a single 33-byte value (instead of a 66-digit hex value). Unlike the string version,
/// session_id here may be passed unprefixed (i.e. 32 bytes instead of 33 with the 05 prefix). Only
/// the *positive* possible ID is returned: the alternative can be computed by flipping the highest
/// bit of byte 32, i.e.: `result[32] ^= 0x80`.
ustring blind15_id(ustring_view session_id, ustring_view server_pk);

/// Computes the 25-blinded id from a session id and server pubkey. Values accepted and
/// returned are hex-encoded.
Expand All @@ -69,6 +84,70 @@ std::string blind25_id(std::string_view session_id, std::string_view server_pk);
/// be passed unprefixed (i.e. 32 bytes instead of 33 with the 05 prefix).
ustring blind25_id(ustring_view session_id, ustring_view server_pk);

/// Computes the 15-blinded id from a 32-byte Ed25519 pubkey, i.e. from the known underlying Ed25519
/// pubkey behind a (X25519) Session ID. Unlike blind15_id, knowing the true Ed25519 pubkey allows
/// thie method to compute the correct sign and so using this does not require considering that the
/// resulting blinded ID might need to have a sign flipped.
///
/// If the `session_id` is a non-null pointer then it must point at an empty string to be populated
/// with the session_id associated with `ed_pubkey`. This is here for consistency with
/// `blinded25_id_from_ed`, but unlike the 25 version, this value is not read if non-empty, and is
/// not an optimization (that is: it is purely for convenience and is no more efficient to use this
/// than it is to compute it yourself).
ustring blinded15_id_from_ed(
ustring_view ed_pubkey, ustring_view server_pk, ustring* session_id = nullptr);

/// Computes the 25-blinded id from a 32-byte Ed25519 pubkey, i.e. from the known underlying Ed25519
/// pubkey behind a (X25519) Session ID. This will be the same as blind25_id (if given the X25519
/// pubkey that the Ed25519 converts to), but is more efficient when the Ed25519 pubkey is already
/// known.
///
/// The session_id argument is provided to optimize input or output of the session ID derived from
/// the Ed25519 pubkey: if already computed, this argument can be a pointer to a 33-byte string
/// containing the precomputed value (to avoid needing to compute it again). If unknown but needed
/// then a pointer to an empty string can be given to computed and stored the value here. Otherwise
/// (if omitted or nullptr) then the value will temporarily computed within the function.
ustring blinded25_id_from_ed(
ustring_view ed_pubkey, ustring_view server_pk, ustring* session_id = nullptr);

/// Computes a 15-blinded key pair.
///
/// Takes the Ed25519 secret key (64 bytes, or 32-byte seed) and the server pubkey (in hex (64
/// digits) or bytes (32 bytes)). Returns the blinded public key and private key (NOT a seed).
///
/// Can optionally also return the blinding factor, k, by providing a pointer to a uc32 (or
/// cleared_uc32); if non-nullptr then k will be written to it.
///
/// It is recommended to pass the full 64-byte libsodium-style secret key for `ed25519_sk` (i.e.
/// seed + appended pubkey) as with just the 32-byte seed the public key has to be recomputed.
std::pair<uc32, cleared_uc32> blind15_key_pair(
ustring_view ed25519_sk, ustring_view server_pk, uc32* k = nullptr);

/// Computes a 25-blinded key pair.
///
/// Takes the Ed25519 secret key (64 bytes, or 32-byte seed) and the server pubkey (in hex (64
/// digits) or bytes (32 bytes)). Returns the blinded public key and private key (NOT a seed).
///
/// Can optionally also return the blinding factor, k', by providing a pointer to a uc32 (or
/// cleared_uc32); if non-nullptr then k' will be written to it, where k' = ±k. Here, `k'` can be
/// negative to cancel out a negative in the true pubkey, which the remote client will always assume
/// is not present when it does a Session ID -> Ed25519 conversion for blinding purposes.
///
/// It is recommended to pass the full 64-byte libsodium-style secret key for `ed25519_sk` (i.e.
/// seed + appended pubkey) as with just the 32-byte seed the public key has to be recomputed.
std::pair<uc32, cleared_uc32> blind25_key_pair(
ustring_view ed25519_sk, ustring_view server_pk, uc32* k_prime = nullptr);

/// Computes a verifiable 15-blinded signature that validates with the blinded pubkey that would
/// be returned from blind15_key_pair().
///
/// Takes the Ed25519 secret key (64 bytes, or 32-byte seed) and the server pubkey (in hex (64
/// digits) or bytes (32 bytes)). Returns the 64-byte signature.
///
/// It is recommended to pass the full 64-byte libsodium-style secret key for `ed25519_sk` (i.e.
/// seed + appended pubkey) as with just the 32-byte seed the public key has to be recomputed.
ustring blind15_sign(ustring_view ed25519_sk, std::string_view server_pk_in, ustring_view message);

/// Computes a verifiable 25-blinded signature that validates with the blinded pubkey that would
/// be returned from blind25_id().
///
Expand All @@ -79,4 +158,13 @@ ustring blind25_id(ustring_view session_id, ustring_view server_pk);
/// seed + appended pubkey) as with just the 32-byte seed the public key has to be recomputed.
ustring blind25_sign(ustring_view ed25519_sk, std::string_view server_pk, ustring_view message);

/// Takes in a standard session_id and returns a flag indicating whether it matches the given
/// blinded_id for a given server_pk.
///
/// Takes either a 15 or 25 blinded_id (66 bytes) and the server pubkey (64 bytes).
///
/// Returns a flag indicating whether the session_id matches the blinded_id.
bool session_id_matches_blinded_id(
std::string_view session_id, std::string_view blinded_id, std::string_view server_pk);

} // namespace session
61 changes: 61 additions & 0 deletions include/session/curve25519.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#pragma once

#ifdef __cplusplus
extern "C" {
#endif

#include <stddef.h>

#include "export.h"

/// API: crypto/session_curve25519_key_pair
///
/// Generates a random curve25519 key pair.
///
/// Inputs:
/// - `curve25519_pk_out` -- [out] pointer to a buffer of 32 bytes where the public key will be
/// written.
/// - `curve25519_sk_out` -- [out] pointer to a buffer of 32 bytes where the private key will be
/// written.
///
/// Outputs:
/// - `bool` -- True if the seed was successfully retrieved, false if failed.
LIBSESSION_EXPORT bool session_curve25519_key_pair(
unsigned char* curve25519_pk_out, /* 32 byte output buffer */
unsigned char* curve25519_sk_out /* 32 byte output buffer */);

/// API: crypto/session_to_curve25519_pubkey
///
/// Generates a curve25519 public key for an ed25519 public key.
///
/// Inputs:
/// - `ed25519_pubkey` -- the ed25519 public key (32 bytes).
/// - `curve25519_pk_out` -- [out] pointer to a buffer of 32 bytes where the public key will be
/// written.
///
/// Outputs:
/// - `bool` -- True if the public key was successfully generated, false if failed.
LIBSESSION_EXPORT bool session_to_curve25519_pubkey(
const unsigned char* ed25519_pubkey, /* 32 bytes */
unsigned char* curve25519_pk_out /* 32 byte output buffer */);

/// API: crypto/session_to_curve25519_seckey
///
/// Generates a curve25519 secret key given given either a libsodium-style secret key, 64
/// bytes. Can also be passed as a 32-byte seed.
///
/// Inputs:
/// - `ed25519_seckey` -- [in] the libsodium-style secret key, 64 bytes. Can also be
/// passed as a 32-byte seed.
/// - `curve25519_sk_out` -- [out] pointer to a buffer of 32 bytes where the secret key will be
/// written.
///
/// Outputs:
/// - `bool` -- True if the secret key was successfully generated, false if failed.
LIBSESSION_EXPORT bool session_to_curve25519_seckey(
const unsigned char* ed25519_seckey, /* 64 bytes */
unsigned char* curve25519_sk_out /* 32 byte output buffer */);

#ifdef __cplusplus
}
#endif
35 changes: 35 additions & 0 deletions include/session/curve25519.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once

#include <array>

#include "types.hpp"

namespace session::curve25519 {

/// Generates a random curve25519 key pair
std::pair<std::array<unsigned char, 32>, std::array<unsigned char, 64>> curve25519_key_pair();

/// API: curve25519/to_curve25519_pubkey
///
/// Generates a curve25519 public key for an ed25519 public key.
///
/// Inputs:
/// - `ed25519_pubkey` -- the ed25519 public key.
///
/// Outputs:
/// - The curve25519 public key
std::array<unsigned char, 32> to_curve25519_pubkey(ustring_view ed25519_pubkey);

/// API: curve25519/to_curve25519_seckey
///
/// Generates a curve25519 secret key given given a libsodium-style secret key, 64
/// bytes.
///
/// Inputs:
/// - `ed25519_seckey` -- the libsodium-style secret key, 64 bytes.
///
/// Outputs:
/// - The curve25519 secret key
std::array<unsigned char, 32> to_curve25519_seckey(ustring_view ed25519_seckey);

} // namespace session::curve25519
Loading

0 comments on commit 343cd41

Please sign in to comment.