mpc_utils - MPC Utility Functions¶
Overview¶
The mpc_utils module provides common utility functions for multi-party computation
(MPC) protocols in the Charm cryptographic library. These utilities support byte/integer
conversions, bit decomposition for OT-based protocols, and Pedersen commitments for
hiding values during secure computation.
This module serves as a foundational building block for threshold ECDSA implementations like DKLS23, providing consistent data handling across all MPC components.
Key Features¶
Byte/Integer Conversion: Consistent big-endian conversion between integers and bytes
Bit Decomposition: LSB-first bit extraction for oblivious transfer protocols
Pedersen Commitments: Information-theoretically hiding, computationally binding commitments
Homomorphic Properties: Commitments support additive homomorphism for secure aggregation
Elliptic Curve Support: Works with any DDH-hard elliptic curve group
Use Cases¶
Oblivious Transfer: Bit decomposition enables OT-based MtA conversion
Zero-Knowledge Proofs: Pedersen commitments provide hiding for ZK protocols
Secure Aggregation: Homomorphic commitment addition for distributed protocols
Protocol Serialization: Consistent byte encoding for network transmission
Example Usage¶
Byte/Integer Conversion:
from charm.toolbox.mpc_utils import int_to_bytes, bytes_to_int
# Convert integer to fixed-length bytes (big-endian)
data = int_to_bytes(256, length=4) # b'\x00\x00\x01\x00'
# Convert back to integer
value = bytes_to_int(data) # 256
Bit Decomposition:
from charm.toolbox.mpc_utils import bit_decompose, bits_to_int
# Decompose value into bits (LSB first)
bits = bit_decompose(value=5, order=2**256, num_bits=4) # [1, 0, 1, 0]
# Reconstruct from bits
reconstructed = bits_to_int(bits, order=2**256) # 5
Pedersen Commitments:
from charm.toolbox.ecgroup import ECGroup, ZR
from charm.toolbox.eccurve import secp256k1
from charm.toolbox.mpc_utils import PedersenCommitment
group = ECGroup(secp256k1)
pc = PedersenCommitment(group)
pc.setup()
# Commit to a value
value = group.random(ZR)
commitment, randomness = pc.commit(value)
# Verify the commitment opens correctly
is_valid = pc.open(commitment, value, randomness) # True
# Homomorphic addition of commitments
c1, r1 = pc.commit(group.init(ZR, 10))
c2, r2 = pc.commit(group.init(ZR, 20))
c_sum = pc.add(c1, c2) # Commits to 30
API Reference¶
MPC Utility Functions for Charm
Common utilities for multi-party computation protocols including: - Byte/integer conversion with consistent big-endian ordering - Bit decomposition and reconstruction for OT-based protocols - Pedersen commitment scheme for hiding commitments
- Authors:
Elton de Souza
- Date:
01/2026
- class mpc_utils.PedersenCommitment(group: ECGroup, g: Any | None = None, h: Any | None = None)[source]¶
Bases:
objectPedersen Commitment Scheme for Elliptic Curve Groups.
Implements the information-theoretically hiding commitment scheme: C = g^value * h^randomness
where g and h are generators with unknown discrete log relationship.
Properties: - Computationally binding (under DLP assumption) - Information-theoretically hiding - Additively homomorphic
Parameters¶
- groupECGroup
An elliptic curve group object
- gGElement, optional
First generator (random if not provided)
- hGElement, optional
Second generator (random if not provided)
Examples¶
>>> from charm.toolbox.eccurve import secp256k1 >>> from charm.toolbox.ecgroup import ECGroup, ZR >>> group = ECGroup(secp256k1) >>> pc = PedersenCommitment(group) >>> pc.setup() >>> value = group.random(ZR) >>> c, r = pc.commit(value) >>> pc.open(c, value, r) True
- add(c1: Any, c2: Any) Any[source]¶
Homomorphically add two commitments.
If c1 = Commit(v1, r1) and c2 = Commit(v2, r2), then c1 * c2 = Commit(v1 + v2, r1 + r2).
Parameters¶
- c1GElement
First commitment
- c2GElement
Second commitment
Returns¶
- GElement
Combined commitment
- commit(value: Any, randomness: Any | None = None) Tuple[Any, Any][source]¶
Create Pedersen commitment: C = g^value * h^randomness.
Parameters¶
- valueZRElement or int
Value to commit to
- randomnessZRElement, optional
Randomness for commitment (generated if not provided)
Returns¶
- tuple
(commitment, randomness)
- property g: Any¶
First generator.
- property h: Any¶
Second generator.
- open(commitment: Any, value: Any, randomness: Any) bool[source]¶
Verify that a commitment opens to the given value.
Parameters¶
- commitmentGElement
The commitment to verify
- valueZRElement or int
The claimed value
- randomnessZRElement
The randomness used in commitment
Returns¶
- bool
True if commitment opens correctly
- mpc_utils.bit_decompose(value: Any, order: int, num_bits: int) List[int][source]¶
Decompose a field element into its bit representation.
The input value is first reduced modulo order to ensure consistent behavior for values at or near the group order boundary.
Parameters¶
- valueZR element or int
The value to decompose (will be reduced mod order)
- orderint
The group order
- num_bitsint
Number of bits to extract
Returns¶
- list of int
List of bits (0 or 1), LSB first
Examples¶
>>> bit_decompose(5, 2**256, 4) [1, 0, 1, 0] >>> bit_decompose(0, 2**256, 4) [0, 0, 0, 0]
- mpc_utils.bits_to_int(bits: List[int], order: int) int[source]¶
Reconstruct an integer from its bit representation, reduced mod order.
This is the inverse of bit_decompose. The result is always reduced modulo the group order to ensure values stay in the valid field range.
Parameters¶
- bitslist of int
List of bits (0 or 1), LSB first
- orderint
The group order
Returns¶
- int
The reconstructed integer, reduced mod order
Examples¶
>>> bits_to_int([1, 0, 1, 0], 2**256) 5 >>> bits_to_int([0, 0, 0, 0], 2**256) 0
- mpc_utils.bytes_to_int(b: bytes) int[source]¶
Convert a byte string to a non-negative integer.
Uses big-endian byte ordering (most significant byte first), which is standard for cryptographic protocols.
Parameters¶
- bbytes
Byte string to convert.
Returns¶
- int
The integer value represented by the bytes.
Examples¶
>>> bytes_to_int(b'\x01\x00') 256 >>> bytes_to_int(b'\x00\x00\x00\x00') 0
- mpc_utils.int_to_bytes(n: int, length: int) bytes[source]¶
Convert a non-negative integer to a fixed-length byte string.
Uses big-endian byte ordering (most significant byte first), which is standard for cryptographic protocols.
Parameters¶
- nint
Non-negative integer to convert. Must fit within length bytes.
- lengthint
Exact number of bytes in the output. Value is zero-padded if needed.
Returns¶
- bytes
Big-endian representation of n with exactly length bytes.
Raises¶
- OverflowError
If n is too large to fit in length bytes.
- ValueError
If n is negative.
Examples¶
>>> int_to_bytes(256, 2) b'\x01\x00' >>> int_to_bytes(0, 4) b'\x00\x00\x00\x00'