Skip to content

Ciphertensor

Defined in stdlib/sequre/types/ciphertensor.codon

Ciphertensor[ctype] wraps a list of CKKS ciphertexts (or plaintexts) into a tensor abstraction with shape tracking, operator overloading, and automatic encoding-mode awareness.

Type parameter

Parameter Typical value Description
ctype Ciphertext or Plaintext The underlying CKKS data type from Lattiseq

Fields

Field Type Description
_data list[ctype] The underlying list of ciphertext/plaintext chunks
shape list[int] Logical tensor shape
slots int Number of CKKS slots per ciphertext (determined by ring degree)
_chunk_size int Elements per chunk
_transposed bool Whether the tensor is in transposed layout
_diagonal_contiguous bool Whether data is stored in diagonal order
_skinny bool Whether the matrix is "skinny" (rows >> cols)
_is_broadcast bool Whether this tensor was produced by broadcasting from all computing parties

Construction

Ciphertensor objects are created via the .enc family of factory methods:

# Encrypt a 2-D ndarray (default encoding chosen automatically)
ct = Ciphertensor.enc(mpc, my_array)

# Encrypt with explicit encoding
ct = Ciphertensor.enc(mpc, my_array, encoding=ENC_DIAG)

# Encrypt in row-wise encoding with padding
ct = Ciphertensor.enc_row_wise(mpc, my_array, padding=16)

Factory methods

Method Description
Ciphertensor.enc(mpc, data, padding=0, encoding="") Encrypt and encode plaintext data into a ciphertensor
Ciphertensor.enc_row_wise(mpc, data, padding=0) Encrypt in row-wise encoding
Ciphertensor.enc_diag_wise(mpc, data, padding=0) Encrypt 2-D data in diagonal-contiguous encoding
Ciphertensor.enc_replicate(mpc, value, shape) Create ciphertensor with a scalar replicated across shape
Ciphertensor.enc_alpern(mpc, data) Encode 3-D arrays in Alpern order
Ciphertensor.zeros(mpc, shape) Zero-initialized ciphertensor with given shape
Ciphertensor.placeholder(shape, slots) Placeholder with uninitialized data
Ciphertensor.like(other) Empty ciphertensor with same properties as other

Properties

Property Type Description
.shape list[int] Logical tensor shape
.slots int CKKS slots per ciphertext
.actual_shape list[int] Shape accounting for transposition and diagonal layout
.cipher_shape list[int] Shape in ciphertext counts (last dim packed by slots)
.size int Total element count
.ndim int Number of dimensions
.T Ciphertensor Lazy transpose (metadata flip only)
.level() int Current noise-growth level

Arithmetic

All operators dispatch to the CKKS evaluator:

Operation HE operation Cost estimate
a + b Ciphertext-ciphertext add ~0.3 ms
a * b Ciphertext-ciphertext multiply + relin ~34.4 ms
a + plain Ciphertext-plaintext add ~0.3 ms
a * plain Ciphertext-plaintext multiply ~1.4 ms
Rotation Galois automorphism ~32.9 ms

Operators

Operator Description
a + b Element-wise addition
a - b Element-wise subtraction
a * b Element-wise multiplication (+ relin)
a @ b Matrix multiplication (adaptive algorithm selection)
a ** n Exponentiation
-a Negation
a > b, a < b Comparisons (via compiler IR pass)

Functional arithmetic

These methods take mpc as the first argument and return a new ciphertensor:

Method Description
.neg(mpc) Element-wise negation
.add(mpc, other) Element-wise addition
.sub(mpc, other) Element-wise subtraction
.mul(mpc, other, ...) Element-wise multiplication
.pow(mpc, p) Element-wise exponentiation

In-place arithmetic

Method Description
.iadd(mpc, other) In-place addition
.isub(mpc, other) In-place subtraction
.imul(mpc, other, no_refresh=False) In-place multiplication (optional refresh suppression)
.ipow(mpc, p) In-place exponentiation
.ineg(mpc) In-place negation
.irotate(mpc, step) In-place homomorphic rotation

Matrix and vector operations

Method Description
.matmul(mpc, other) Matrix multiplication with adaptive MHE/MPC algorithm selection
.dot(mpc, other, axis) Dot product along axis
.dot(mpc, axis) Self dot product along axis
.aggregate(mpc) Aggregate distributed shares to party 0
.sum(mpc, axis) Sum reduction along axis
.reduce_add(mpc, keep_dims=True) Sum all elements of a 1-D tensor
.reduce_add_tiled(mpc, tile_size) Tiled sum reduction for 1-D/2-D tensors

Note

matmul automatically selects between pure-MHE and MPC ↔ MHE switching paths based on a cost estimator when AllowMPCSwitch is active.

Encoding modes

The @mhe_enc_opt compiler pass selects the optimal encoding strategy per matrix multiplication:

Mode Constant Description
Row-wise ENC_ROW Each ciphertext holds one row
Column-wise ENC_COL Each ciphertext holds one column
Diagonal ENC_DIAG Diagonal packing for matrix-vector products

Shape manipulation

Method Description
.expand_dims(axis=0) Insert a dimension of size 1
.pad(mpc, new_size) Pad 1-D tensor with zeros
.pad_with_value(val, size, axis, mpc) Pad with a specific value
.resize(mpc, shape) Resize 1-D tensor to new shape
.concat(mpc, other, axis) Concatenate along axis (returns new tensor)
.iconcat(mpc, other, axis) In-place concatenation
.extend(mpc, other) Extend tensor with another (1-D or 2-D)
.append(other) Append rows to 2-D tensor
.pop() Remove last row
.filter(mask) Boolean mask filtering
.replicate(mpc, new_size) Extend 1-D tensor by recursive patch copying
.local_broadcast(mpc, target_shape) Broadcast to target shape locally

Encoding and layout

Method Description
.rotate(mpc, step) Homomorphic rotation (returns new tensor)
.shift(mpc, step) Shift 1-D tensor with zero fill and shape expansion
.diagonal(idx) Extract diagonal from diagonal-contiguous 2-D tensor
.diagonal_contig(mpc) Convert to diagonal-contiguous encoding
.diagonal_transpose(mpc) Transpose diagonal-contiguous layout
.mask(mpc, i) One-hot mask for element i of a 1-D tensor
.getitemdup(mpc, i, new_size) Duplicate a single element to fill a new size
.actual_transpose(mpc) Materialize actual transpose (vs. lazy .T)
.get_actual(mpc) Resolve pending transposition/diagonality
.iget_actual(mpc) In-place get_actual
.I(mpc) Identity matrix ciphertensor (requires 2-D)

Conversion and decryption

Method Description
.copy(shallow=False) Deep or shallow copy
.astype(T) Type conversion (currently identity)
.decrypt(mpc, source_pid=-2) Decrypt to plaintext
.decode(mpc) Decode plaintext tensor to ndarray
.reveal(mpc, source_pid=-2) Decrypt and decode in one step
.via_mpc(mpc, fn, *args) Execute a function through the MPC layer (E2S → fn → S2E)

Indexing and iteration

Method Description
ct[i] Index / slice (requires compiler IR pass)
ct[i] = v Set element (requires compiler IR pass)
for row in ct Iterate over rows (asserts not transposed, ndim > 1)
bool(ct) True if the tensor contains data

Utility

Method Description
.set(other) Replace all internal state from another tensor
.validate() Assert internal consistency
.get_matmul_cost(other) Cost estimate for algorithm selection
Ciphertensor.requires_collective(a, b) Check if a collective op is needed (transposition mismatch)