mpt-crypto
Confidential Multi-Purpose Tokens Cryptographic Library
Loading...
Searching...
No Matches
elgamal.c File Reference

EC-ElGamal Encryption for Confidential Balances. More...

#include "secp256k1_mpt.h"
#include <openssl/rand.h>
#include <openssl/sha.h>
#include <string.h>
#include <stdlib.h>
Include dependency graph for elgamal.c:

Go to the source code of this file.

Functions

static int pubkey_equal (const secp256k1_context *ctx, const secp256k1_pubkey *pk1, const secp256k1_pubkey *pk2)
static int compute_amount_point (const secp256k1_context *ctx, secp256k1_pubkey *mG, uint64_t amount)
int secp256k1_elgamal_generate_keypair (const secp256k1_context *ctx, unsigned char *privkey, secp256k1_pubkey *pubkey)
 Generates a new secp256k1 key pair.
int secp256k1_elgamal_encrypt (const secp256k1_context *ctx, secp256k1_pubkey *c1, secp256k1_pubkey *c2, const secp256k1_pubkey *pubkey_Q, uint64_t amount, const unsigned char *blinding_factor)
 Encrypts a 64-bit amount using ElGamal.
int secp256k1_elgamal_decrypt (const secp256k1_context *ctx, uint64_t *amount, const secp256k1_pubkey *c1, const secp256k1_pubkey *c2, const unsigned char *privkey)
 Decrypts an ElGamal ciphertext to recover the amount.
int secp256k1_elgamal_add (const secp256k1_context *ctx, secp256k1_pubkey *sum_c1, secp256k1_pubkey *sum_c2, const secp256k1_pubkey *a_c1, const secp256k1_pubkey *a_c2, const secp256k1_pubkey *b_c1, const secp256k1_pubkey *b_c2)
 Homomorphically adds two ElGamal ciphertexts.
int secp256k1_elgamal_subtract (const secp256k1_context *ctx, secp256k1_pubkey *diff_c1, secp256k1_pubkey *diff_c2, const secp256k1_pubkey *a_c1, const secp256k1_pubkey *a_c2, const secp256k1_pubkey *b_c1, const secp256k1_pubkey *b_c2)
 Homomorphically subtracts two ElGamal ciphertexts.
int generate_canonical_encrypted_zero (const secp256k1_context *ctx, secp256k1_pubkey *enc_zero_c1, secp256k1_pubkey *enc_zero_c2, const secp256k1_pubkey *pubkey, const unsigned char *account_id, const unsigned char *mpt_issuance_id)
 Generates the canonical encrypted zero for a given MPT token instance.
int secp256k1_elgamal_verify_encryption (const secp256k1_context *ctx, const secp256k1_pubkey *c1, const secp256k1_pubkey *c2, const secp256k1_pubkey *pubkey_Q, uint64_t amount, const unsigned char *blinding_factor)

Detailed Description

EC-ElGamal Encryption for Confidential Balances.

This module implements additive homomorphic encryption using the ElGamal scheme over the secp256k1 elliptic curve. It provides the core mechanism for representing confidential balances and transferring value on the ledger.

Encryption Scheme: Given a public key \( Q = sk \cdot G \) and a plaintext amount \( m \), encryption with randomness \( r \) produces a ciphertext pair \( (C_1, C_2) \):

  • \( C_1 = r \cdot G \) (Ephemeral public key)
  • \( C_2 = m \cdot G + r \cdot Q \) (Masked amount)

Homomorphism: The scheme is additively homomorphic:

\[ Enc(m_1) + Enc(m_2) = (C_{1,1}+C_{1,2}, C_{2,1}+C_{2,2}) = Enc(m_1 + m_2) \]

This allows validators to update balances (e.g., add incoming transfers) without decrypting them.

Decryption (Discrete Logarithm): Decryption involves two steps:

  1. Remove the mask: \( M = C_2 - sk \cdot C_1 = m \cdot G \).
  2. Recover \( m \) from \( M \): This requires solving the Discrete Logarithm Problem (DLP) for \( m \). Since balances are 64-bit integers but typically small in "human" terms, this implementation uses an optimized search for ranges relevant to transaction processing (e.g., 0 to 1,000,000).

Canonical Zero: To ensure deterministic ledger state for empty accounts, a "Canonical Encrypted Zero" is defined using randomness derived deterministically from the account ID and token ID.

See also
[Spec (ConfidentialMPT_20260201.pdf) Section 3.2.2] ElGamal Encryption

Definition in file elgamal.c.

Function Documentation

◆ compute_amount_point()

int compute_amount_point ( const secp256k1_context * ctx,
secp256k1_pubkey * mG,
uint64_t amount )
static

Definition at line 48 of file elgamal.c.

Here is the caller graph for this function:

◆ generate_canonical_encrypted_zero()

int generate_canonical_encrypted_zero ( const secp256k1_context * ctx,
secp256k1_pubkey * enc_zero_c1,
secp256k1_pubkey * enc_zero_c2,
const secp256k1_pubkey * pubkey,
const unsigned char * account_id,
const unsigned char * mpt_issuance_id )

Generates the canonical encrypted zero for a given MPT token instance.

This ciphertext represents a zero balance for a specific account's holding of a token defined by its MPTokenIssuanceID.

Parameters
[in]ctxA pointer to a valid secp256k1 context.
[out]enc_zero_c1The C1 component of the canonical ciphertext.
[out]enc_zero_c2The C2 component of the canonical ciphertext.
[in]pubkeyThe ElGamal public key of the account holder.
[in]account_idA pointer to the 20-byte AccountID.
[in]mpt_issuance_idA pointer to the 24-byte MPTokenIssuanceID.
Returns
1 on success, 0 on failure.

Definition at line 211 of file elgamal.c.

Here is the call graph for this function:

◆ pubkey_equal()

int pubkey_equal ( const secp256k1_context * ctx,
const secp256k1_pubkey * pk1,
const secp256k1_pubkey * pk2 )
static

Definition at line 44 of file elgamal.c.

Here is the caller graph for this function:

◆ secp256k1_elgamal_add()

int secp256k1_elgamal_add ( const secp256k1_context * ctx,
secp256k1_pubkey * sum_c1,
secp256k1_pubkey * sum_c2,
const secp256k1_pubkey * a_c1,
const secp256k1_pubkey * a_c2,
const secp256k1_pubkey * b_c1,
const secp256k1_pubkey * b_c2 )

Homomorphically adds two ElGamal ciphertexts.

Definition at line 164 of file elgamal.c.

◆ secp256k1_elgamal_decrypt()

int secp256k1_elgamal_decrypt ( const secp256k1_context * ctx,
uint64_t * amount,
const secp256k1_pubkey * c1,
const secp256k1_pubkey * c2,
const unsigned char * privkey )

Decrypts an ElGamal ciphertext to recover the amount.

Definition at line 111 of file elgamal.c.

Here is the call graph for this function:

◆ secp256k1_elgamal_encrypt()

int secp256k1_elgamal_encrypt ( const secp256k1_context * ctx,
secp256k1_pubkey * c1,
secp256k1_pubkey * c2,
const secp256k1_pubkey * pubkey_Q,
uint64_t amount,
const unsigned char * blinding_factor )

Encrypts a 64-bit amount using ElGamal.

Definition at line 79 of file elgamal.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ secp256k1_elgamal_generate_keypair()

int secp256k1_elgamal_generate_keypair ( const secp256k1_context * ctx,
unsigned char * privkey,
secp256k1_pubkey * pubkey )

Generates a new secp256k1 key pair.

Definition at line 61 of file elgamal.c.

◆ secp256k1_elgamal_subtract()

int secp256k1_elgamal_subtract ( const secp256k1_context * ctx,
secp256k1_pubkey * diff_c1,
secp256k1_pubkey * diff_c2,
const secp256k1_pubkey * a_c1,
const secp256k1_pubkey * a_c2,
const secp256k1_pubkey * b_c1,
const secp256k1_pubkey * b_c2 )

Homomorphically subtracts two ElGamal ciphertexts.

Definition at line 184 of file elgamal.c.

◆ secp256k1_elgamal_verify_encryption()

int secp256k1_elgamal_verify_encryption ( const secp256k1_context * ctx,
const secp256k1_pubkey * c1,
const secp256k1_pubkey * c2,
const secp256k1_pubkey * pubkey_Q,
uint64_t amount,
const unsigned char * blinding_factor )

Verifies that (c1, c2) is a valid ElGamal encryption of 'amount' for 'pubkey_Q' using the revealed 'blinding_factor'.

Definition at line 262 of file elgamal.c.

Here is the call graph for this function: