Source

context.ts

  1. import { ContextData, ContextDataConstructorOptions } from './context-data'
  2. import { EncryptionParameters } from './encryption-parameters'
  3. import { ParmsIdType, ParmsIdTypeConstructorOptions } from './parms-id-type'
  4. import { Instance, Library, LoaderOptions } from './seal'
  5. import { SecurityLevel } from './security-level'
  6. export type ContextDependencyOptions = {
  7. readonly ParmsIdType: ParmsIdTypeConstructorOptions
  8. readonly ContextData: ContextDataConstructorOptions
  9. readonly SecurityLevel: SecurityLevel
  10. }
  11. export type ContextDependencies = {
  12. ({
  13. ParmsIdType,
  14. ContextData,
  15. SecurityLevel
  16. }: ContextDependencyOptions): ContextConstructorOptions
  17. }
  18. export type ContextConstructorOptions = {
  19. (
  20. encryptionParams: EncryptionParameters,
  21. expandModChain?: boolean,
  22. securityLevel?: SecurityLevel
  23. ): Context
  24. }
  25. export type Context = {
  26. readonly instance: Instance
  27. readonly unsafeInject: (instance: Instance) => void
  28. readonly delete: () => void
  29. readonly toHuman: () => string
  30. readonly getContextData: (parmsId: ParmsIdType) => ContextData
  31. readonly keyContextData: ContextData
  32. readonly firstContextData: ContextData
  33. readonly lastContextData: ContextData
  34. readonly parametersSet: () => boolean
  35. readonly keyParmsId: ParmsIdType
  36. readonly firstParmsId: ParmsIdType
  37. readonly lastParmsId: ParmsIdType
  38. readonly usingKeyswitching: boolean
  39. }
  40. const ContextConstructor =
  41. (library: Library): ContextDependencies =>
  42. ({
  43. ParmsIdType,
  44. ContextData,
  45. SecurityLevel
  46. }: ContextDependencyOptions): ContextConstructorOptions =>
  47. (
  48. encryptionParams,
  49. expandModChain = true,
  50. securityLevel = SecurityLevel.tc128
  51. ): Context => {
  52. // Static methods
  53. const Constructor = library.SEALContext
  54. let _instance = new Constructor(
  55. encryptionParams.instance,
  56. expandModChain,
  57. securityLevel
  58. ) as Instance
  59. /**
  60. * @implements Context
  61. */
  62. /**
  63. * @interface Context
  64. */
  65. return {
  66. /**
  67. * Get the underlying WASM instance
  68. *
  69. * @private
  70. * @readonly
  71. * @name Context#instance
  72. * @type {Instance}
  73. */
  74. get instance() {
  75. return _instance
  76. },
  77. /**
  78. * Inject this object with a raw WASM instance. No type checking is performed.
  79. *
  80. * @private
  81. * @function
  82. * @name Context#unsafeInject
  83. * @param {Instance} instance WASM instance
  84. */
  85. unsafeInject(instance: Instance) {
  86. if (_instance) {
  87. _instance.delete()
  88. _instance = undefined
  89. }
  90. _instance = instance
  91. },
  92. /**
  93. * Delete the underlying WASM instance.
  94. *
  95. * Should be called before dereferencing this object to prevent the
  96. * WASM heap from growing indefinitely.
  97. * @function
  98. * @name Context#delete
  99. */
  100. delete() {
  101. if (_instance) {
  102. _instance.delete()
  103. _instance = undefined
  104. }
  105. },
  106. /**
  107. * Returns the context parameters in a human readable string format.
  108. *
  109. * @private
  110. * @function
  111. * @name Context#toString
  112. * @returns {string} Context details as a string
  113. */
  114. toHuman(): string {
  115. return _instance.toHuman()
  116. },
  117. /**
  118. * Returns the ContextData corresponding to encryption parameters with a given
  119. * parmsId. If parameters with the given parmsId are not found then the
  120. * function returns nullptr.
  121. *
  122. * @function
  123. * @name Context#getContextData
  124. * @param {ParmsIdType} parmsId Specific id to return ContextData for
  125. * @returns {ContextData} ContextData corresponding to encryption parameters
  126. */
  127. getContextData(parmsId: ParmsIdType): ContextData {
  128. const instance = _instance.getContextData(parmsId.instance)
  129. const contextData = ContextData()
  130. contextData.unsafeInject(instance)
  131. return contextData
  132. },
  133. /**
  134. * The ContextData corresponding to encryption parameters that are used for keys.
  135. *
  136. * @readonly
  137. * @name Context#keyContextData
  138. * @type {ContextData}
  139. */
  140. get keyContextData() {
  141. const instance = _instance.keyContextData()
  142. const contextData = ContextData()
  143. contextData.unsafeInject(instance)
  144. return contextData
  145. },
  146. /**
  147. * The ContextData corresponding to the first encryption parameters that are used for data.
  148. *
  149. * @readonly
  150. * @name Context#firstContextData
  151. * @type {ContextData}
  152. */
  153. get firstContextData() {
  154. const instance = _instance.firstContextData()
  155. const contextData = ContextData()
  156. contextData.unsafeInject(instance)
  157. return contextData
  158. },
  159. /**
  160. * Returns the ContextData corresponding to the last encryption parameters that are used for data.
  161. *
  162. * @readonly
  163. * @name Context#lastContextData
  164. * @type {ContextData}
  165. */
  166. get lastContextData() {
  167. const instance = _instance.lastContextData()
  168. const contextData = ContextData()
  169. contextData.unsafeInject(instance)
  170. return contextData
  171. },
  172. /**
  173. * Whether the encryption parameters are set in a way that is considered valid by
  174. * Microsoft SEAL, the variable parameters_set is set to true.
  175. *
  176. * @function
  177. * @name Context#parametersSet
  178. * @type {boolean}
  179. */
  180. parametersSet() {
  181. return _instance.parametersSet()
  182. },
  183. /**
  184. * Returns a ParmsIdType corresponding to the set of encryption parameters that are used for keys.
  185. *
  186. * @readonly
  187. * @name Context#keyParmsId
  188. * @type {ParmsIdType}
  189. */
  190. get keyParmsId() {
  191. const instance = _instance.keyParmsId()
  192. const parmsId = ParmsIdType()
  193. parmsId.inject(instance)
  194. return parmsId
  195. },
  196. /**
  197. * Returns a ParmsIdType corresponding to the first encryption parameters that are used for data.
  198. *
  199. * @readonly
  200. * @name Context#firstParmsId
  201. * @type {ParmsIdType}
  202. */
  203. get firstParmsId() {
  204. const instance = _instance.firstParmsId()
  205. const parmsId = ParmsIdType()
  206. parmsId.inject(instance)
  207. return parmsId
  208. },
  209. /**
  210. * The ParmsIdType corresponding to the last encryption parameters that are used for data.
  211. *
  212. * @readonly
  213. * @name Context#lastParmsId
  214. * @type {ParmsIdType}
  215. */
  216. get lastParmsId() {
  217. const instance = _instance.lastParmsId()
  218. const parmsId = ParmsIdType()
  219. parmsId.inject(instance)
  220. return parmsId
  221. },
  222. /**
  223. * Whether the coefficient modulus supports keyswitching. In practice,
  224. * support for keyswitching is required by Evaluator.relinearize,
  225. * Evaluator.applyGalois, and all rotation and conjugation operations. For
  226. * keyswitching to be available, the coefficient modulus parameter must consist
  227. * of at least two prime number factors.
  228. *
  229. * @readonly
  230. * @name Context#usingKeyswitching
  231. * @type {boolean}
  232. */
  233. get usingKeyswitching() {
  234. return _instance.usingKeyswitching()
  235. }
  236. }
  237. }
  238. export const ContextInit = ({ loader }: LoaderOptions): ContextDependencies => {
  239. const library: Library = loader.library
  240. return ContextConstructor(library)
  241. }