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.
- mplang/__init__.py +21 -45
- mplang/py.typed +13 -0
- mplang/v1/__init__.py +157 -0
- mplang/v1/_device.py +602 -0
- mplang/{analysis → v1/analysis}/__init__.py +1 -1
- mplang/{analysis → v1/analysis}/diagram.py +5 -7
- mplang/v1/core/__init__.py +157 -0
- mplang/{core → v1/core}/cluster.py +30 -14
- mplang/{core → v1/core}/comm.py +5 -1
- mplang/{core → v1/core}/context_mgr.py +1 -1
- mplang/{core/dtype.py → v1/core/dtypes.py} +44 -2
- mplang/{core → v1/core}/expr/__init__.py +7 -7
- mplang/{core → v1/core}/expr/ast.py +13 -14
- mplang/{core → v1/core}/expr/evaluator.py +65 -24
- mplang/{core → v1/core}/expr/printer.py +24 -18
- mplang/{core → v1/core}/expr/transformer.py +3 -3
- mplang/{core → v1/core}/expr/utils.py +2 -2
- mplang/{core → v1/core}/expr/visitor.py +1 -1
- mplang/{core → v1/core}/expr/walk.py +1 -1
- mplang/{core → v1/core}/interp.py +6 -6
- mplang/{core → v1/core}/mpir.py +23 -16
- mplang/{core → v1/core}/mpobject.py +6 -6
- mplang/{core → v1/core}/mptype.py +13 -10
- mplang/{core → v1/core}/pfunc.py +4 -4
- mplang/{core → v1/core}/primitive.py +106 -201
- mplang/{core → v1/core}/table.py +36 -8
- mplang/{core → v1/core}/tensor.py +1 -1
- mplang/{core → v1/core}/tracer.py +9 -9
- mplang/{api.py → v1/host.py} +38 -6
- mplang/v1/kernels/__init__.py +41 -0
- mplang/{kernels → v1/kernels}/base.py +1 -1
- mplang/v1/kernels/basic.py +240 -0
- mplang/{kernels → v1/kernels}/context.py +42 -27
- mplang/{kernels → v1/kernels}/crypto.py +44 -37
- mplang/v1/kernels/fhe.py +858 -0
- mplang/{kernels → v1/kernels}/mock_tee.py +12 -13
- mplang/{kernels → v1/kernels}/phe.py +263 -57
- mplang/{kernels → v1/kernels}/spu.py +137 -48
- mplang/{kernels → v1/kernels}/sql_duckdb.py +12 -15
- mplang/{kernels → v1/kernels}/stablehlo.py +30 -23
- mplang/v1/kernels/value.py +626 -0
- mplang/{ops → v1/ops}/__init__.py +5 -16
- mplang/{ops → v1/ops}/base.py +2 -5
- mplang/{ops/builtin.py → v1/ops/basic.py} +34 -26
- mplang/v1/ops/crypto.py +262 -0
- mplang/v1/ops/fhe.py +272 -0
- mplang/{ops → v1/ops}/jax_cc.py +33 -68
- mplang/v1/ops/nnx_cc.py +168 -0
- mplang/{ops → v1/ops}/phe.py +16 -4
- mplang/{ops → v1/ops}/spu.py +3 -5
- mplang/v1/ops/sql_cc.py +303 -0
- mplang/{ops → v1/ops}/tee.py +9 -24
- mplang/{protos → v1/protos}/v1alpha1/mpir_pb2.pyi +71 -21
- mplang/v1/protos/v1alpha1/value_pb2.py +34 -0
- mplang/v1/protos/v1alpha1/value_pb2.pyi +169 -0
- mplang/{runtime → v1/runtime}/__init__.py +2 -2
- mplang/v1/runtime/channel.py +230 -0
- mplang/{runtime → v1/runtime}/cli.py +35 -20
- mplang/{runtime → v1/runtime}/client.py +19 -8
- mplang/{runtime → v1/runtime}/communicator.py +59 -15
- mplang/{runtime → v1/runtime}/data_providers.py +80 -19
- mplang/{runtime → v1/runtime}/driver.py +30 -12
- mplang/v1/runtime/link_comm.py +196 -0
- mplang/{runtime → v1/runtime}/server.py +58 -42
- mplang/{runtime → v1/runtime}/session.py +57 -71
- mplang/{runtime → v1/runtime}/simulation.py +55 -28
- mplang/v1/simp/api.py +353 -0
- mplang/{simp → v1/simp}/mpi.py +8 -9
- mplang/{simp/__init__.py → v1/simp/party.py} +19 -145
- mplang/{simp → v1/simp}/random.py +21 -22
- mplang/v1/simp/smpc.py +238 -0
- mplang/v1/utils/table_utils.py +185 -0
- mplang/v2/__init__.py +424 -0
- mplang/v2/backends/__init__.py +57 -0
- mplang/v2/backends/bfv_impl.py +705 -0
- mplang/v2/backends/channel.py +217 -0
- mplang/v2/backends/crypto_impl.py +723 -0
- mplang/v2/backends/field_impl.py +454 -0
- mplang/v2/backends/func_impl.py +107 -0
- mplang/v2/backends/phe_impl.py +148 -0
- mplang/v2/backends/simp_design.md +136 -0
- mplang/v2/backends/simp_driver/__init__.py +41 -0
- mplang/v2/backends/simp_driver/http.py +168 -0
- mplang/v2/backends/simp_driver/mem.py +280 -0
- mplang/v2/backends/simp_driver/ops.py +135 -0
- mplang/v2/backends/simp_driver/state.py +60 -0
- mplang/v2/backends/simp_driver/values.py +52 -0
- mplang/v2/backends/simp_worker/__init__.py +29 -0
- mplang/v2/backends/simp_worker/http.py +354 -0
- mplang/v2/backends/simp_worker/mem.py +102 -0
- mplang/v2/backends/simp_worker/ops.py +167 -0
- mplang/v2/backends/simp_worker/state.py +49 -0
- mplang/v2/backends/spu_impl.py +275 -0
- mplang/v2/backends/spu_state.py +187 -0
- mplang/v2/backends/store_impl.py +62 -0
- mplang/v2/backends/table_impl.py +838 -0
- mplang/v2/backends/tee_impl.py +215 -0
- mplang/v2/backends/tensor_impl.py +519 -0
- mplang/v2/cli.py +603 -0
- mplang/v2/cli_guide.md +122 -0
- mplang/v2/dialects/__init__.py +36 -0
- mplang/v2/dialects/bfv.py +665 -0
- mplang/v2/dialects/crypto.py +689 -0
- mplang/v2/dialects/dtypes.py +378 -0
- mplang/v2/dialects/field.py +210 -0
- mplang/v2/dialects/func.py +135 -0
- mplang/v2/dialects/phe.py +723 -0
- mplang/v2/dialects/simp.py +944 -0
- mplang/v2/dialects/spu.py +349 -0
- mplang/v2/dialects/store.py +63 -0
- mplang/v2/dialects/table.py +407 -0
- mplang/v2/dialects/tee.py +346 -0
- mplang/v2/dialects/tensor.py +1175 -0
- mplang/v2/edsl/README.md +279 -0
- mplang/v2/edsl/__init__.py +99 -0
- mplang/v2/edsl/context.py +311 -0
- mplang/v2/edsl/graph.py +463 -0
- mplang/v2/edsl/jit.py +62 -0
- mplang/v2/edsl/object.py +53 -0
- mplang/v2/edsl/primitive.py +284 -0
- mplang/v2/edsl/printer.py +119 -0
- mplang/v2/edsl/registry.py +207 -0
- mplang/v2/edsl/serde.py +375 -0
- mplang/v2/edsl/tracer.py +614 -0
- mplang/v2/edsl/typing.py +816 -0
- mplang/v2/kernels/Makefile +30 -0
- mplang/v2/kernels/__init__.py +23 -0
- mplang/v2/kernels/gf128.cpp +148 -0
- mplang/v2/kernels/ldpc.cpp +82 -0
- mplang/v2/kernels/okvs.cpp +283 -0
- mplang/v2/kernels/okvs_opt.cpp +291 -0
- mplang/v2/kernels/py_kernels.py +398 -0
- mplang/v2/libs/collective.py +330 -0
- mplang/v2/libs/device/__init__.py +51 -0
- mplang/v2/libs/device/api.py +813 -0
- mplang/v2/libs/device/cluster.py +352 -0
- mplang/v2/libs/ml/__init__.py +23 -0
- mplang/v2/libs/ml/sgb.py +1861 -0
- mplang/v2/libs/mpc/__init__.py +41 -0
- mplang/v2/libs/mpc/_utils.py +99 -0
- mplang/v2/libs/mpc/analytics/__init__.py +35 -0
- mplang/v2/libs/mpc/analytics/aggregation.py +372 -0
- mplang/v2/libs/mpc/analytics/groupby.md +99 -0
- mplang/v2/libs/mpc/analytics/groupby.py +331 -0
- mplang/v2/libs/mpc/analytics/permutation.py +386 -0
- mplang/v2/libs/mpc/common/constants.py +39 -0
- mplang/v2/libs/mpc/ot/__init__.py +32 -0
- mplang/v2/libs/mpc/ot/base.py +222 -0
- mplang/v2/libs/mpc/ot/extension.py +477 -0
- mplang/v2/libs/mpc/ot/silent.py +217 -0
- mplang/v2/libs/mpc/psi/__init__.py +40 -0
- mplang/v2/libs/mpc/psi/cuckoo.py +228 -0
- mplang/v2/libs/mpc/psi/okvs.py +49 -0
- mplang/v2/libs/mpc/psi/okvs_gct.py +79 -0
- mplang/v2/libs/mpc/psi/oprf.py +310 -0
- mplang/v2/libs/mpc/psi/rr22.py +344 -0
- mplang/v2/libs/mpc/psi/unbalanced.py +200 -0
- mplang/v2/libs/mpc/vole/__init__.py +31 -0
- mplang/v2/libs/mpc/vole/gilboa.py +327 -0
- mplang/v2/libs/mpc/vole/ldpc.py +383 -0
- mplang/v2/libs/mpc/vole/silver.py +336 -0
- mplang/v2/runtime/__init__.py +15 -0
- mplang/v2/runtime/dialect_state.py +41 -0
- mplang/v2/runtime/interpreter.py +871 -0
- mplang/v2/runtime/object_store.py +194 -0
- mplang/v2/runtime/value.py +141 -0
- {mplang_nightly-0.1.dev158.dist-info → mplang_nightly-0.1.dev268.dist-info}/METADATA +24 -17
- mplang_nightly-0.1.dev268.dist-info/RECORD +180 -0
- {mplang_nightly-0.1.dev158.dist-info → mplang_nightly-0.1.dev268.dist-info}/WHEEL +1 -1
- mplang/core/__init__.py +0 -92
- mplang/device.py +0 -340
- mplang/kernels/builtin.py +0 -207
- mplang/ops/crypto.py +0 -109
- mplang/ops/ibis_cc.py +0 -139
- mplang/ops/sql.py +0 -61
- mplang/protos/v1alpha1/mpir_pb2_grpc.py +0 -3
- mplang/runtime/link_comm.py +0 -131
- mplang/simp/smpc.py +0 -201
- mplang/utils/table_utils.py +0 -73
- mplang_nightly-0.1.dev158.dist-info/RECORD +0 -77
- /mplang/{core → v1/core}/mask.py +0 -0
- /mplang/{protos → v1/protos}/v1alpha1/mpir_pb2.py +0 -0
- /mplang/{runtime → v1/runtime}/exceptions.py +0 -0
- /mplang/{runtime → v1/runtime}/http_api.md +0 -0
- /mplang/{kernels → v1/simp}/__init__.py +0 -0
- /mplang/{utils → v1/utils}/__init__.py +0 -0
- /mplang/{utils → v1/utils}/crypto.py +0 -0
- /mplang/{utils → v1/utils}/func_utils.py +0 -0
- /mplang/{utils → v1/utils}/spu_utils.py +0 -0
- {mplang_nightly-0.1.dev158.dist-info → mplang_nightly-0.1.dev268.dist-info}/entry_points.txt +0 -0
- {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
|
+
]
|