sum

Engine.sum(ciphertext, roll_key, axis)
Returns a ciphertext that is the sum of the input ciphertext along a given axis. A level is consumed only if the engine is not configured for bootstrapping and the ciphertext is at the maximum allowable level for a given parameter.
  • Input:
    • Ciphertext
    • RollKey
      • RollKey is not required for sum over the 0 axis.
    • axis: int, optional
      • Axis along which a sum is performed. The default, axis=None, will sum all of the elements of the input ciphertext.
  • Output:
    • Ciphertext
      • Each row of a ciphertext holds Engine.slot_count slots.
      • With axis=None, the total sum is stored in every slot of a single row.
      • With axis=0, the rows are added slot by slot into a single row.
      • With axis=1, the sum of each row is stored in every slot of that row, and the number of rows is unchanged.

Warning

  • The matrix form does not yet support this operation.

Examples

Sum along all axes

import numpy as np
from desilofhe import Engine

engine = Engine()
secret_key = engine.create_secret_key()
roll_key = engine.create_roll_key(secret_key)
slot_count = engine.slot_count  # 8192

message = np.repeat([1, 2], slot_count)
ciphertext = engine.encrypt(message, secret_key)

# each row holds engine.slot_count (8192) slots
# contents of ciphertext:
# [[1, 1, ..., 1],
#  [2, 2, ..., 2]]

summed = engine.sum(ciphertext, roll_key)

# contents of summed:
# [[24576, 24576, ..., 24576]]

Sum along the 0-axis

import numpy as np
from desilofhe import Engine

engine = Engine()
secret_key = engine.create_secret_key()
roll_key = engine.create_roll_key(secret_key)
slot_count = engine.slot_count  # 8192

message = np.repeat([1, 2], slot_count)
ciphertext = engine.encrypt(message, secret_key)

# each row holds engine.slot_count (8192) slots
# contents of ciphertext:
# [[1, 1, ..., 1],
#  [2, 2, ..., 2]]

summed = engine.sum(ciphertext, roll_key, axis=0)

# contents of summed:
# [[3, 3, ..., 3]]

Sum along the 1-axis

import numpy as np
from desilofhe import Engine

engine = Engine()
secret_key = engine.create_secret_key()
roll_key = engine.create_roll_key(secret_key)
slot_count = engine.slot_count  # 8192

message = np.repeat([1, 2], slot_count)
ciphertext = engine.encrypt(message, secret_key)

# each row holds engine.slot_count (8192) slots
# contents of ciphertext:
# [[1, 1, ..., 1],
#  [2, 2, ..., 2]]

summed = engine.sum(ciphertext, roll_key, axis=1)

# contents of summed:
# [[8192, 8192, ..., 8192],
#  [16384, 16384, ..., 16384]]

Engine.sum(ciphertext, axis)
Returns a ciphertext that is the sum of the rows of the input ciphertext, without a key. Only axis=0 is supported.
  • Input:
    • Ciphertext
    • axis: int
      • Must be 0.
  • Output:
    • Ciphertext

Warning

  • The matrix form does not yet support this operation.
import numpy as np
from desilofhe import Engine

engine = Engine()
secret_key = engine.create_secret_key()
slot_count = engine.slot_count  # 8192

message = np.repeat([1, 2], slot_count)
ciphertext = engine.encrypt(message, secret_key)
summed = engine.sum(ciphertext, axis=0)
# [[3, 3, ..., 3]]
Engine.sum(ciphertext, evaluation_key, axis)
Returns a ciphertext that is the sum of the input ciphertext along a given axis, using the roll key bundled in the evaluation key. A level is consumed only if the engine is not configured for bootstrapping and the ciphertext is at the maximum allowable level for a given parameter.
  • Input:
    • Ciphertext
    • EvaluationKey
    • axis: int, optional
      • Axis along which a sum is performed. The default, axis=None, will sum all of the elements of the input ciphertext.
  • Output:
    • Ciphertext
      • Each row of a ciphertext holds Engine.slot_count slots.
      • With axis=None, the total sum is stored in every slot of a single row.
      • With axis=0, the rows are added slot by slot into a single row.
      • With axis=1, the sum of each row is stored in every slot of that row, and the number of rows is unchanged.

Warning

  • The matrix form does not yet support this operation.

Examples

Sum along all axes

import numpy as np
from desilofhe import Engine

engine = Engine()
secret_key = engine.create_secret_key()
evaluation_key = engine.create_evaluation_key(secret_key)
slot_count = engine.slot_count  # 8192

message = np.repeat([1, 2], slot_count)
ciphertext = engine.encrypt(message, secret_key)

# each row holds engine.slot_count (8192) slots
# contents of ciphertext:
# [[1, 1, ..., 1],
#  [2, 2, ..., 2]]

summed = engine.sum(ciphertext, evaluation_key)

# contents of summed:
# [[24576, 24576, ..., 24576]]

Sum along the 0-axis

import numpy as np
from desilofhe import Engine

engine = Engine()
secret_key = engine.create_secret_key()
evaluation_key = engine.create_evaluation_key(secret_key)
slot_count = engine.slot_count  # 8192

message = np.repeat([1, 2], slot_count)
ciphertext = engine.encrypt(message, secret_key)

# each row holds engine.slot_count (8192) slots
# contents of ciphertext:
# [[1, 1, ..., 1],
#  [2, 2, ..., 2]]

summed = engine.sum(ciphertext, evaluation_key, axis=0)

# contents of summed:
# [[3, 3, ..., 3]]

Sum along the 1-axis

import numpy as np
from desilofhe import Engine

engine = Engine()
secret_key = engine.create_secret_key()
evaluation_key = engine.create_evaluation_key(secret_key)
slot_count = engine.slot_count  # 8192

message = np.repeat([1, 2], slot_count)
ciphertext = engine.encrypt(message, secret_key)

# each row holds engine.slot_count (8192) slots
# contents of ciphertext:
# [[1, 1, ..., 1],
#  [2, 2, ..., 2]]

summed = engine.sum(ciphertext, evaluation_key, axis=1)

# contents of summed:
# [[8192, 8192, ..., 8192],
#  [16384, 16384, ..., 16384]]

Engine.sum(ciphertext, bootstrap_key, axis=None)
Returns a ciphertext that is the sum of the input ciphertext along a given axis, using the fixed roll keys contained in the bootstrap key. The engine must be created with Engine(bootstrap=True).
  • Input:
    • Ciphertext
    • BootstrapKey
    • axis: int, optional
      • Axis along which a sum is performed. The default, axis=None, will sum all of the elements of the input ciphertext.
  • Output:
    • Ciphertext
      • Each row of a ciphertext holds Engine.slot_count slots.
      • With axis=None, the total sum is stored in every slot of a single row.
      • With axis=0, the rows are added slot by slot into a single row.
      • With axis=1, the sum of each row is stored in every slot of that row, and the number of rows is unchanged.

Warning

  • The matrix form does not yet support this operation.

Examples

Sum along all axes

import numpy as np
from desilofhe import Engine

engine = Engine(bootstrap=True)
secret_key = engine.create_secret_key()
bootstrap_key = engine.create_bootstrap_key(secret_key)
slot_count = engine.slot_count  # 32768

message = np.repeat([1, 2], slot_count)
ciphertext = engine.encrypt(message, secret_key)

# each row holds engine.slot_count (32768) slots
# contents of ciphertext:
# [[1, 1, ..., 1],
#  [2, 2, ..., 2]]

summed = engine.sum(ciphertext, bootstrap_key)

# contents of summed:
# [[98304, 98304, ..., 98304]]

Sum along the 0-axis

import numpy as np
from desilofhe import Engine

engine = Engine(bootstrap=True)
secret_key = engine.create_secret_key()
bootstrap_key = engine.create_bootstrap_key(secret_key)
slot_count = engine.slot_count  # 32768

message = np.repeat([1, 2], slot_count)
ciphertext = engine.encrypt(message, secret_key)

# each row holds engine.slot_count (32768) slots
# contents of ciphertext:
# [[1, 1, ..., 1],
#  [2, 2, ..., 2]]

summed = engine.sum(ciphertext, bootstrap_key, axis=0)

# contents of summed:
# [[3, 3, ..., 3]]

Sum along the 1-axis

import numpy as np
from desilofhe import Engine

engine = Engine(bootstrap=True)
secret_key = engine.create_secret_key()
bootstrap_key = engine.create_bootstrap_key(secret_key)
slot_count = engine.slot_count  # 32768

message = np.repeat([1, 2], slot_count)
ciphertext = engine.encrypt(message, secret_key)

# each row holds engine.slot_count (32768) slots
# contents of ciphertext:
# [[1, 1, ..., 1],
#  [2, 2, ..., 2]]

summed = engine.sum(ciphertext, bootstrap_key, axis=1)

# contents of summed:
# [[32768, 32768, ..., 32768],
#  [65536, 65536, ..., 65536]]