Skip to main content

HomOps Reference

HomCompare

Soft comparison of two encrypted values: near 1 when a > b, near 0 when a < b.

CpComparison
RunsServer
Changes shapeYes - broadcast
Changes scaleYes - via nested ops
Levels spentTunable - sign poly depth
RotatesNo
KeysSquare key

What it does

HomCompare approximates a soft greater-than mask for two encrypted values:
comp(a, b) = (approx_sign(a − b) + 1) / 2
The result is near 1 when a > b and near 0 when a < b. It is a composite, not a registered leaf: the compiler expands it into HomSign plus subtract / add arithmetic (including HomSub for the difference).
Default input domain is [left, right] = [-1, 1]. Internally Sign is built with scale=0.5 and a remapped domain [left − right, right − left], so for the defaults Sign sees [-2, 2]. Use it for encrypted greater-than masks, and as the building block for HomMin, HomMax, and HomMinMax.

Signature

HomCompare(
    x_accuracy=10,
    y_accuracy=10,
    left=-1.0,
    right=1.0,
    tol=1e-8,
    rows_budget=None,
)
Two ciphertext inputs. No set_data.

Parameters

ParameterTypeDefaultDescription
x_accuracyint10Horizontal accuracy for the nested HomSign.
y_accuracyint10Vertical accuracy for the nested Sign approximation.
left, rightfloat-1.0, 1.0Assumed domain for inputs a and b. Defaults are [-1, 1] (not [0, 1]).
tolfloat1e-8Poly eval tolerance, forwarded to Sign / PolyEval stages.
rows_budgetsequenceNoneRestricts which levels the nested mod-switches may spend. See rows_budget.
Rules that depend on the value
SettingRuleIf you break it
left, rightThe difference a − b should lie in Sign's remapped domain [left − right, right − left]. For defaults [-1, 1], that is [-2, 2].Wrong results, not an error. Values outside the fitted domain produce garbage silently.

Requirements

  • Square key. Nested Sign / PolyEval stages need the square key (generated for you during key generation).
  • Two inputs. Broadcast-compatible encrypted tensors; their difference should fit Sign's remapped domain.
  • Level headroom. Depth follows the nested Sign poly stages. Plan like a multi-stage PolyEval.
  • Not a leaf. HomCompare expands into nested ops; it is not a registered backend leaf.

Shape effect - yes

Rule: element-wise broadcast of a − b, then Sign. The output shape matches the broadcast shape of the difference.

Scale effect - yes

Scale follows the nested HomSign multi-stage PolyEval, plus a cheap add of 0.5. Check the compile-time simulation for the output scale.
How scale moves through a pipeline is on Ciphertext state - Scale.

Level budget

Levels spent are set by the nested Sign poly depth (tunable via x_accuracy / y_accuracy), plus negligible cost for the final + 0.5.
How primes are organized in the chain is explained on Level budget - The chain.

Keys

Square key (relinearization key). Required through the nested Sign / PolyEval children. Generated for you during key generation. No rotation key.

Example

Build a soft greater-than mask:
pipeline.pyPYTHON
from lattica_build.operators import HomCompare

cmp = HomCompare(x_accuracy=12, y_accuracy=12, left=-1.0, right=1.0)
# mask = cmp(a, b)   # ≈ 1 if a > b

See also