mplang-nightly 0.1.dev158__py3-none-any.whl → 0.1.dev268__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. mplang/__init__.py +21 -45
  2. mplang/py.typed +13 -0
  3. mplang/v1/__init__.py +157 -0
  4. mplang/v1/_device.py +602 -0
  5. mplang/{analysis → v1/analysis}/__init__.py +1 -1
  6. mplang/{analysis → v1/analysis}/diagram.py +5 -7
  7. mplang/v1/core/__init__.py +157 -0
  8. mplang/{core → v1/core}/cluster.py +30 -14
  9. mplang/{core → v1/core}/comm.py +5 -1
  10. mplang/{core → v1/core}/context_mgr.py +1 -1
  11. mplang/{core/dtype.py → v1/core/dtypes.py} +44 -2
  12. mplang/{core → v1/core}/expr/__init__.py +7 -7
  13. mplang/{core → v1/core}/expr/ast.py +13 -14
  14. mplang/{core → v1/core}/expr/evaluator.py +65 -24
  15. mplang/{core → v1/core}/expr/printer.py +24 -18
  16. mplang/{core → v1/core}/expr/transformer.py +3 -3
  17. mplang/{core → v1/core}/expr/utils.py +2 -2
  18. mplang/{core → v1/core}/expr/visitor.py +1 -1
  19. mplang/{core → v1/core}/expr/walk.py +1 -1
  20. mplang/{core → v1/core}/interp.py +6 -6
  21. mplang/{core → v1/core}/mpir.py +23 -16
  22. mplang/{core → v1/core}/mpobject.py +6 -6
  23. mplang/{core → v1/core}/mptype.py +13 -10
  24. mplang/{core → v1/core}/pfunc.py +4 -4
  25. mplang/{core → v1/core}/primitive.py +106 -201
  26. mplang/{core → v1/core}/table.py +36 -8
  27. mplang/{core → v1/core}/tensor.py +1 -1
  28. mplang/{core → v1/core}/tracer.py +9 -9
  29. mplang/{api.py → v1/host.py} +38 -6
  30. mplang/v1/kernels/__init__.py +41 -0
  31. mplang/{kernels → v1/kernels}/base.py +1 -1
  32. mplang/v1/kernels/basic.py +240 -0
  33. mplang/{kernels → v1/kernels}/context.py +42 -27
  34. mplang/{kernels → v1/kernels}/crypto.py +44 -37
  35. mplang/v1/kernels/fhe.py +858 -0
  36. mplang/{kernels → v1/kernels}/mock_tee.py +12 -13
  37. mplang/{kernels → v1/kernels}/phe.py +263 -57
  38. mplang/{kernels → v1/kernels}/spu.py +137 -48
  39. mplang/{kernels → v1/kernels}/sql_duckdb.py +12 -15
  40. mplang/{kernels → v1/kernels}/stablehlo.py +30 -23
  41. mplang/v1/kernels/value.py +626 -0
  42. mplang/{ops → v1/ops}/__init__.py +5 -16
  43. mplang/{ops → v1/ops}/base.py +2 -5
  44. mplang/{ops/builtin.py → v1/ops/basic.py} +34 -26
  45. mplang/v1/ops/crypto.py +262 -0
  46. mplang/v1/ops/fhe.py +272 -0
  47. mplang/{ops → v1/ops}/jax_cc.py +33 -68
  48. mplang/v1/ops/nnx_cc.py +168 -0
  49. mplang/{ops → v1/ops}/phe.py +16 -4
  50. mplang/{ops → v1/ops}/spu.py +3 -5
  51. mplang/v1/ops/sql_cc.py +303 -0
  52. mplang/{ops → v1/ops}/tee.py +9 -24
  53. mplang/{protos → v1/protos}/v1alpha1/mpir_pb2.pyi +71 -21
  54. mplang/v1/protos/v1alpha1/value_pb2.py +34 -0
  55. mplang/v1/protos/v1alpha1/value_pb2.pyi +169 -0
  56. mplang/{runtime → v1/runtime}/__init__.py +2 -2
  57. mplang/v1/runtime/channel.py +230 -0
  58. mplang/{runtime → v1/runtime}/cli.py +35 -20
  59. mplang/{runtime → v1/runtime}/client.py +19 -8
  60. mplang/{runtime → v1/runtime}/communicator.py +59 -15
  61. mplang/{runtime → v1/runtime}/data_providers.py +80 -19
  62. mplang/{runtime → v1/runtime}/driver.py +30 -12
  63. mplang/v1/runtime/link_comm.py +196 -0
  64. mplang/{runtime → v1/runtime}/server.py +58 -42
  65. mplang/{runtime → v1/runtime}/session.py +57 -71
  66. mplang/{runtime → v1/runtime}/simulation.py +55 -28
  67. mplang/v1/simp/api.py +353 -0
  68. mplang/{simp → v1/simp}/mpi.py +8 -9
  69. mplang/{simp/__init__.py → v1/simp/party.py} +19 -145
  70. mplang/{simp → v1/simp}/random.py +21 -22
  71. mplang/v1/simp/smpc.py +238 -0
  72. mplang/v1/utils/table_utils.py +185 -0
  73. mplang/v2/__init__.py +424 -0
  74. mplang/v2/backends/__init__.py +57 -0
  75. mplang/v2/backends/bfv_impl.py +705 -0
  76. mplang/v2/backends/channel.py +217 -0
  77. mplang/v2/backends/crypto_impl.py +723 -0
  78. mplang/v2/backends/field_impl.py +454 -0
  79. mplang/v2/backends/func_impl.py +107 -0
  80. mplang/v2/backends/phe_impl.py +148 -0
  81. mplang/v2/backends/simp_design.md +136 -0
  82. mplang/v2/backends/simp_driver/__init__.py +41 -0
  83. mplang/v2/backends/simp_driver/http.py +168 -0
  84. mplang/v2/backends/simp_driver/mem.py +280 -0
  85. mplang/v2/backends/simp_driver/ops.py +135 -0
  86. mplang/v2/backends/simp_driver/state.py +60 -0
  87. mplang/v2/backends/simp_driver/values.py +52 -0
  88. mplang/v2/backends/simp_worker/__init__.py +29 -0
  89. mplang/v2/backends/simp_worker/http.py +354 -0
  90. mplang/v2/backends/simp_worker/mem.py +102 -0
  91. mplang/v2/backends/simp_worker/ops.py +167 -0
  92. mplang/v2/backends/simp_worker/state.py +49 -0
  93. mplang/v2/backends/spu_impl.py +275 -0
  94. mplang/v2/backends/spu_state.py +187 -0
  95. mplang/v2/backends/store_impl.py +62 -0
  96. mplang/v2/backends/table_impl.py +838 -0
  97. mplang/v2/backends/tee_impl.py +215 -0
  98. mplang/v2/backends/tensor_impl.py +519 -0
  99. mplang/v2/cli.py +603 -0
  100. mplang/v2/cli_guide.md +122 -0
  101. mplang/v2/dialects/__init__.py +36 -0
  102. mplang/v2/dialects/bfv.py +665 -0
  103. mplang/v2/dialects/crypto.py +689 -0
  104. mplang/v2/dialects/dtypes.py +378 -0
  105. mplang/v2/dialects/field.py +210 -0
  106. mplang/v2/dialects/func.py +135 -0
  107. mplang/v2/dialects/phe.py +723 -0
  108. mplang/v2/dialects/simp.py +944 -0
  109. mplang/v2/dialects/spu.py +349 -0
  110. mplang/v2/dialects/store.py +63 -0
  111. mplang/v2/dialects/table.py +407 -0
  112. mplang/v2/dialects/tee.py +346 -0
  113. mplang/v2/dialects/tensor.py +1175 -0
  114. mplang/v2/edsl/README.md +279 -0
  115. mplang/v2/edsl/__init__.py +99 -0
  116. mplang/v2/edsl/context.py +311 -0
  117. mplang/v2/edsl/graph.py +463 -0
  118. mplang/v2/edsl/jit.py +62 -0
  119. mplang/v2/edsl/object.py +53 -0
  120. mplang/v2/edsl/primitive.py +284 -0
  121. mplang/v2/edsl/printer.py +119 -0
  122. mplang/v2/edsl/registry.py +207 -0
  123. mplang/v2/edsl/serde.py +375 -0
  124. mplang/v2/edsl/tracer.py +614 -0
  125. mplang/v2/edsl/typing.py +816 -0
  126. mplang/v2/kernels/Makefile +30 -0
  127. mplang/v2/kernels/__init__.py +23 -0
  128. mplang/v2/kernels/gf128.cpp +148 -0
  129. mplang/v2/kernels/ldpc.cpp +82 -0
  130. mplang/v2/kernels/okvs.cpp +283 -0
  131. mplang/v2/kernels/okvs_opt.cpp +291 -0
  132. mplang/v2/kernels/py_kernels.py +398 -0
  133. mplang/v2/libs/collective.py +330 -0
  134. mplang/v2/libs/device/__init__.py +51 -0
  135. mplang/v2/libs/device/api.py +813 -0
  136. mplang/v2/libs/device/cluster.py +352 -0
  137. mplang/v2/libs/ml/__init__.py +23 -0
  138. mplang/v2/libs/ml/sgb.py +1861 -0
  139. mplang/v2/libs/mpc/__init__.py +41 -0
  140. mplang/v2/libs/mpc/_utils.py +99 -0
  141. mplang/v2/libs/mpc/analytics/__init__.py +35 -0
  142. mplang/v2/libs/mpc/analytics/aggregation.py +372 -0
  143. mplang/v2/libs/mpc/analytics/groupby.md +99 -0
  144. mplang/v2/libs/mpc/analytics/groupby.py +331 -0
  145. mplang/v2/libs/mpc/analytics/permutation.py +386 -0
  146. mplang/v2/libs/mpc/common/constants.py +39 -0
  147. mplang/v2/libs/mpc/ot/__init__.py +32 -0
  148. mplang/v2/libs/mpc/ot/base.py +222 -0
  149. mplang/v2/libs/mpc/ot/extension.py +477 -0
  150. mplang/v2/libs/mpc/ot/silent.py +217 -0
  151. mplang/v2/libs/mpc/psi/__init__.py +40 -0
  152. mplang/v2/libs/mpc/psi/cuckoo.py +228 -0
  153. mplang/v2/libs/mpc/psi/okvs.py +49 -0
  154. mplang/v2/libs/mpc/psi/okvs_gct.py +79 -0
  155. mplang/v2/libs/mpc/psi/oprf.py +310 -0
  156. mplang/v2/libs/mpc/psi/rr22.py +344 -0
  157. mplang/v2/libs/mpc/psi/unbalanced.py +200 -0
  158. mplang/v2/libs/mpc/vole/__init__.py +31 -0
  159. mplang/v2/libs/mpc/vole/gilboa.py +327 -0
  160. mplang/v2/libs/mpc/vole/ldpc.py +383 -0
  161. mplang/v2/libs/mpc/vole/silver.py +336 -0
  162. mplang/v2/runtime/__init__.py +15 -0
  163. mplang/v2/runtime/dialect_state.py +41 -0
  164. mplang/v2/runtime/interpreter.py +871 -0
  165. mplang/v2/runtime/object_store.py +194 -0
  166. mplang/v2/runtime/value.py +141 -0
  167. {mplang_nightly-0.1.dev158.dist-info → mplang_nightly-0.1.dev268.dist-info}/METADATA +24 -17
  168. mplang_nightly-0.1.dev268.dist-info/RECORD +180 -0
  169. {mplang_nightly-0.1.dev158.dist-info → mplang_nightly-0.1.dev268.dist-info}/WHEEL +1 -1
  170. mplang/core/__init__.py +0 -92
  171. mplang/device.py +0 -340
  172. mplang/kernels/builtin.py +0 -207
  173. mplang/ops/crypto.py +0 -109
  174. mplang/ops/ibis_cc.py +0 -139
  175. mplang/ops/sql.py +0 -61
  176. mplang/protos/v1alpha1/mpir_pb2_grpc.py +0 -3
  177. mplang/runtime/link_comm.py +0 -131
  178. mplang/simp/smpc.py +0 -201
  179. mplang/utils/table_utils.py +0 -73
  180. mplang_nightly-0.1.dev158.dist-info/RECORD +0 -77
  181. /mplang/{core → v1/core}/mask.py +0 -0
  182. /mplang/{protos → v1/protos}/v1alpha1/mpir_pb2.py +0 -0
  183. /mplang/{runtime → v1/runtime}/exceptions.py +0 -0
  184. /mplang/{runtime → v1/runtime}/http_api.md +0 -0
  185. /mplang/{kernels → v1/simp}/__init__.py +0 -0
  186. /mplang/{utils → v1/utils}/__init__.py +0 -0
  187. /mplang/{utils → v1/utils}/crypto.py +0 -0
  188. /mplang/{utils → v1/utils}/func_utils.py +0 -0
  189. /mplang/{utils → v1/utils}/spu_utils.py +0 -0
  190. {mplang_nightly-0.1.dev158.dist-info → mplang_nightly-0.1.dev268.dist-info}/entry_points.txt +0 -0
  191. {mplang_nightly-0.1.dev158.dist-info → mplang_nightly-0.1.dev268.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,346 @@
1
+ # Copyright 2025 Ant Group Co., Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """TEE (Trusted Execution Environment) dialect for mplang.v2 EDSL.
16
+
17
+ This dialect provides primitives for TEE remote attestation, enabling secure
18
+ computation where:
19
+ 1. Data providers can verify they're communicating with genuine TEE hardware
20
+ 2. The TEE proves it's running the expected code (measurement)
21
+ 3. Session keys are established via attested key exchange
22
+
23
+ Architecture:
24
+ PublicKey (from crypto.kem_keygen)
25
+ ↓ quote_gen(pk)
26
+ Quote (cryptographic attestation proof)
27
+ ↓ (transfer to verifier)
28
+ ↓ attest(quote)
29
+ AttestedKey[curve] (verified TEE public key)
30
+ ↓ crypto.kem_derive(local_sk, attested_pk)
31
+ SharedSecret (secure channel with TEE)
32
+
33
+ Supported Platforms:
34
+ - "mock": Insecure mock for local testing (default)
35
+ - "sgx": Intel SGX (DCAP attestation)
36
+ - "tdx": Intel TDX
37
+ - "sev": AMD SEV-SNP
38
+
39
+ Example:
40
+ ```python
41
+ from mplang.v2.dialects import tee, crypto
42
+
43
+ # On TEE side: generate keypair and quote
44
+ sk, pk = crypto.kem_keygen("x25519")
45
+ quote = tee.quote_gen(pk) # Bind public key in attestation
46
+
47
+ # On verifier side: verify quote and get attested key
48
+ attested_pk = tee.attest(quote)
49
+
50
+ # Establish secure channel
51
+ verifier_sk, verifier_pk = crypto.kem_keygen("x25519")
52
+ shared_secret = crypto.kem_derive(verifier_sk, attested_pk)
53
+ ```
54
+
55
+ Security Note:
56
+ The mock implementation is NOT SECURE and should only be used for
57
+ development and testing. Production deployments must use real TEE
58
+ backends (SGX, TDX, SEV).
59
+ """
60
+
61
+ from __future__ import annotations
62
+
63
+ from typing import Any, ClassVar, Literal
64
+
65
+ import mplang.v2.edsl as el
66
+ import mplang.v2.edsl.typing as elt
67
+ from mplang.v2.dialects.crypto import PublicKeyType
68
+ from mplang.v2.edsl import serde
69
+
70
+ # ==============================================================================
71
+ # --- Type Definitions
72
+ # ==============================================================================
73
+
74
+ KeyCurve = Literal["x25519", "secp256k1"]
75
+
76
+
77
+ @serde.register_class
78
+ class QuoteType(elt.BaseType):
79
+ """Type for a TEE attestation quote.
80
+
81
+ A quote is a cryptographic proof that:
82
+ 1. Code is running in a genuine TEE (signed by hardware)
83
+ 2. The TEE is running expected code (measurement/MRENCLAVE)
84
+ 3. The quote binds a specific ephemeral public key
85
+
86
+ The quote can be verified by anyone with access to the TEE vendor's
87
+ root certificates (Intel, AMD, etc.).
88
+ """
89
+
90
+ def __str__(self) -> str:
91
+ return "TEEQuote"
92
+
93
+ def __repr__(self) -> str:
94
+ return "QuoteType()"
95
+
96
+ def __eq__(self, other: object) -> bool:
97
+ return isinstance(other, QuoteType)
98
+
99
+ def __hash__(self) -> int:
100
+ return hash("QuoteType")
101
+
102
+ # --- Serde methods ---
103
+ _serde_kind: ClassVar[str] = "tee.QuoteType"
104
+
105
+ def to_json(self) -> dict[str, Any]:
106
+ return {}
107
+
108
+ @classmethod
109
+ def from_json(cls, data: dict[str, Any]) -> QuoteType:
110
+ return cls()
111
+
112
+
113
+ @serde.register_class
114
+ class AttestedKeyType(elt.BaseType):
115
+ """Type for an attested public key extracted from a verified quote.
116
+
117
+ This represents a public key that has been cryptographically proven to
118
+ belong to a genuine TEE running specific code. It can be used for:
119
+ - Key exchange (KEM/ECDH) to establish secure channels
120
+ - Encryption directly to the TEE
121
+
122
+ The key is trusted because:
123
+ 1. The quote signature chains to a trusted TEE vendor root
124
+ 2. The measurement in the quote matches expected code
125
+ 3. The public key is bound in the quote's report_data
126
+
127
+ Attributes:
128
+ curve: Cryptographic curve of the key
129
+ """
130
+
131
+ def __init__(self, curve: str = "x25519"):
132
+ self.curve: KeyCurve = curve # type: ignore[assignment]
133
+
134
+ def __str__(self) -> str:
135
+ return f"AttestedKey[{self.curve}]"
136
+
137
+ def __repr__(self) -> str:
138
+ return f"AttestedKeyType(curve={self.curve!r})"
139
+
140
+ def __eq__(self, other: object) -> bool:
141
+ if not isinstance(other, AttestedKeyType):
142
+ return False
143
+ return self.curve == other.curve
144
+
145
+ def __hash__(self) -> int:
146
+ return hash(("AttestedKeyType", self.curve))
147
+
148
+ # --- Serde methods ---
149
+ _serde_kind: ClassVar[str] = "tee.AttestedKeyType"
150
+
151
+ def to_json(self) -> dict[str, Any]:
152
+ return {"curve": self.curve}
153
+
154
+ @classmethod
155
+ def from_json(cls, data: dict[str, Any]) -> AttestedKeyType:
156
+ return cls(curve=data["curve"])
157
+
158
+
159
+ @serde.register_class
160
+ class MeasurementType(elt.BaseType):
161
+ """Type for TEE code measurement (e.g., MRENCLAVE, MRTD).
162
+
163
+ Represents a cryptographic hash of the code and initial configuration
164
+ running inside the TEE. Used to verify the TEE is running expected code.
165
+ """
166
+
167
+ def __str__(self) -> str:
168
+ return "TEEMeasurement"
169
+
170
+ def __repr__(self) -> str:
171
+ return "MeasurementType()"
172
+
173
+ def __eq__(self, other: object) -> bool:
174
+ return isinstance(other, MeasurementType)
175
+
176
+ def __hash__(self) -> int:
177
+ return hash("MeasurementType")
178
+
179
+ # --- Serde methods ---
180
+ _serde_kind: ClassVar[str] = "tee.MeasurementType"
181
+
182
+ def to_json(self) -> dict[str, Any]:
183
+ return {}
184
+
185
+ @classmethod
186
+ def from_json(cls, data: dict[str, Any]) -> MeasurementType:
187
+ return cls()
188
+
189
+
190
+ # ==============================================================================
191
+ # --- Primitives
192
+ # ==============================================================================
193
+
194
+ quote_gen_p = el.Primitive[el.Object]("tee.quote_gen")
195
+ attest_p = el.Primitive[el.Object]("tee.attest")
196
+ get_measurement_p = el.Primitive[el.Object]("tee.get_measurement")
197
+
198
+
199
+ # ==============================================================================
200
+ # --- Abstract Evaluation (Type Inference)
201
+ # ==============================================================================
202
+
203
+
204
+ @quote_gen_p.def_abstract_eval
205
+ def _quote_gen_ae(
206
+ pk: elt.BaseType,
207
+ ) -> QuoteType:
208
+ """Generate a TEE quote binding the provided public key.
209
+
210
+ Args:
211
+ pk: Public key to bind in the quote (must be PublicKeyType from crypto.kem_keygen)
212
+
213
+ Returns:
214
+ QuoteType representing the attestation proof
215
+
216
+ Raises:
217
+ TypeError: If pk is not a PublicKeyType
218
+ """
219
+ if not isinstance(pk, PublicKeyType):
220
+ raise TypeError(
221
+ f"quote_gen expects PublicKeyType (from crypto.kem_keygen), "
222
+ f"got {type(pk).__name__}"
223
+ )
224
+ return QuoteType()
225
+
226
+
227
+ @attest_p.def_abstract_eval
228
+ def _attest_ae(
229
+ quote: QuoteType,
230
+ *,
231
+ expected_curve: KeyCurve = "x25519",
232
+ ) -> AttestedKeyType:
233
+ """Verify a quote and extract the attested public key.
234
+
235
+ Args:
236
+ quote: The TEE quote to verify
237
+ expected_curve: Expected curve of the bound key
238
+
239
+ Returns:
240
+ AttestedKeyType containing the verified public key
241
+ """
242
+ return AttestedKeyType(curve=expected_curve)
243
+
244
+
245
+ @get_measurement_p.def_abstract_eval
246
+ def _get_measurement_ae(
247
+ quote: QuoteType,
248
+ ) -> MeasurementType:
249
+ """Extract the measurement (MRENCLAVE/MRTD) from a quote.
250
+
251
+ Args:
252
+ quote: The TEE quote
253
+
254
+ Returns:
255
+ MeasurementType containing the code measurement
256
+ """
257
+ return MeasurementType()
258
+
259
+
260
+ # ==============================================================================
261
+ # --- User-facing API (Helper Functions)
262
+ # ==============================================================================
263
+
264
+
265
+ def quote_gen(
266
+ pk: el.Object,
267
+ ) -> el.Object:
268
+ """Generate a TEE attestation quote binding the provided public key.
269
+
270
+ This operation runs inside the TEE and produces a quote that:
271
+ 1. Proves the code is running in genuine TEE hardware
272
+ 2. Contains the measurement (hash) of the running code
273
+ 3. Binds the provided public key in the report_data
274
+
275
+ Args:
276
+ pk: Public key to bind (typically from crypto.kem_keygen)
277
+
278
+ Returns:
279
+ Object[QuoteType] - The attestation quote
280
+
281
+ Example:
282
+ >>> sk, pk = crypto.kem_keygen("x25519")
283
+ >>> quote = tee.quote_gen(pk) # Bind pk in attestation
284
+ """
285
+ return quote_gen_p.bind(pk)
286
+
287
+
288
+ def attest(
289
+ quote: el.Object,
290
+ expected_curve: KeyCurve = "x25519",
291
+ ) -> el.Object:
292
+ """Verify a TEE quote and extract the attested public key.
293
+
294
+ This operation runs on the verifier side and:
295
+ 1. Validates the quote signature against TEE vendor roots
296
+ 2. Checks the measurement matches expected values
297
+ 3. Extracts the bound public key
298
+
299
+ After verification, the returned key is trusted to belong to a genuine
300
+ TEE running the expected code.
301
+
302
+ Args:
303
+ quote: The TEE quote to verify
304
+ expected_curve: Expected curve of the bound key
305
+
306
+ Returns:
307
+ Object[AttestedKeyType] - The verified public key
308
+
309
+ Raises:
310
+ AttestationError: If verification fails
311
+
312
+ Example:
313
+ >>> attested_pk = tee.attest(quote)
314
+ >>> # Now safe to derive shared secret with TEE
315
+ >>> shared = crypto.kem_derive(my_sk, attested_pk)
316
+ """
317
+ return attest_p.bind(quote, expected_curve=expected_curve)
318
+
319
+
320
+ def get_measurement(quote: el.Object) -> el.Object:
321
+ """Extract the code measurement from a quote.
322
+
323
+ The measurement is a cryptographic hash of the code running in the TEE.
324
+ For SGX this is MRENCLAVE, for TDX this is MRTD, etc.
325
+
326
+ Args:
327
+ quote: The TEE quote
328
+
329
+ Returns:
330
+ Object[MeasurementType] - The code measurement
331
+ """
332
+ return get_measurement_p.bind(quote)
333
+
334
+
335
+ __all__ = [
336
+ "AttestedKeyType",
337
+ "KeyCurve",
338
+ "MeasurementType",
339
+ "QuoteType",
340
+ "attest",
341
+ "attest_p",
342
+ "get_measurement",
343
+ "get_measurement_p",
344
+ "quote_gen",
345
+ "quote_gen_p",
346
+ ]