mplang-nightly 0.1.dev265__py3-none-any.whl → 0.1.dev266__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/v2/backends/crypto_impl.py +95 -0
- mplang/v2/dialects/crypto.py +101 -0
- mplang/v2/libs/device/api.py +30 -11
- {mplang_nightly-0.1.dev265.dist-info → mplang_nightly-0.1.dev266.dist-info}/METADATA +1 -1
- {mplang_nightly-0.1.dev265.dist-info → mplang_nightly-0.1.dev266.dist-info}/RECORD +8 -8
- {mplang_nightly-0.1.dev265.dist-info → mplang_nightly-0.1.dev266.dist-info}/WHEEL +0 -0
- {mplang_nightly-0.1.dev265.dist-info → mplang_nightly-0.1.dev266.dist-info}/entry_points.txt +0 -0
- {mplang_nightly-0.1.dev265.dist-info → mplang_nightly-0.1.dev266.dist-info}/licenses/LICENSE +0 -0
|
@@ -614,6 +614,101 @@ def kem_derive_impl(
|
|
|
614
614
|
return SymmetricKeyValue(suite=suite, key_bytes=secret)
|
|
615
615
|
|
|
616
616
|
|
|
617
|
+
@crypto.hkdf_p.def_impl
|
|
618
|
+
def hkdf_impl(
|
|
619
|
+
interpreter: Interpreter,
|
|
620
|
+
op: Operation,
|
|
621
|
+
secret: SymmetricKeyValue | TensorValue,
|
|
622
|
+
) -> SymmetricKeyValue:
|
|
623
|
+
"""HKDF key derivation implementation using SHA-256.
|
|
624
|
+
|
|
625
|
+
Implements RFC 5869 HKDF with HMAC-SHA256. This is the NIST SP 800-56C
|
|
626
|
+
compliant way to derive symmetric keys from ECDH shared secrets.
|
|
627
|
+
|
|
628
|
+
Current implementation supports only SHA-256. Future versions will add
|
|
629
|
+
SHA-512, SHA3-256, and BLAKE2b support.
|
|
630
|
+
|
|
631
|
+
Security Notes:
|
|
632
|
+
- Uses salt=None (defaults to 32-byte all-zero salt per RFC 5869)
|
|
633
|
+
- ONLY SAFE for high-entropy IKM (e.g., 256-bit ECDH shared secrets)
|
|
634
|
+
- NOT suitable for: passwords, low-entropy secrets, or repeated key derivations
|
|
635
|
+
- For session keys with same ECDH pair: use unique 'info' per session
|
|
636
|
+
|
|
637
|
+
Per NIST SP 800-56C Rev. 2:
|
|
638
|
+
"If the IKM is already cryptographically strong (e.g., from ECDH),
|
|
639
|
+
a salt may not be necessary, but using one does not hurt."
|
|
640
|
+
|
|
641
|
+
Args:
|
|
642
|
+
interpreter: Runtime interpreter context
|
|
643
|
+
op: Operation node containing attributes (info, hash_algo)
|
|
644
|
+
secret: Input key material (IKM) as SymmetricKeyValue or TensorValue
|
|
645
|
+
Must be high-entropy (≥256 bits) for security with salt=None
|
|
646
|
+
|
|
647
|
+
Returns:
|
|
648
|
+
SymmetricKeyValue with suite="hkdf-{hash_algo}" and 32-byte key_bytes
|
|
649
|
+
|
|
650
|
+
Raises:
|
|
651
|
+
TypeError: If secret is not SymmetricKeyValue or TensorValue
|
|
652
|
+
ValueError: If info parameter is empty (required for domain separation)
|
|
653
|
+
NotImplementedError: If hash_algo is not "sha256"
|
|
654
|
+
"""
|
|
655
|
+
from cryptography.hazmat.primitives import hashes
|
|
656
|
+
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
|
|
657
|
+
|
|
658
|
+
# Extract operation attributes
|
|
659
|
+
info_str = op.attrs.get("info", "")
|
|
660
|
+
hash_algo = (
|
|
661
|
+
op.attrs.get("hash_algo", "sha256").lower().replace("-", "").replace("_", "")
|
|
662
|
+
)
|
|
663
|
+
|
|
664
|
+
# Validate info parameter (REQUIRED for domain separation per NIST)
|
|
665
|
+
if not info_str:
|
|
666
|
+
raise ValueError(
|
|
667
|
+
"HKDF requires non-empty 'info' parameter for domain separation. "
|
|
668
|
+
"The info string binds the derived key to a specific protocol/context. "
|
|
669
|
+
"Recommended format: 'namespace/component/purpose/version'"
|
|
670
|
+
)
|
|
671
|
+
|
|
672
|
+
info_bytes = info_str.encode("utf-8")
|
|
673
|
+
|
|
674
|
+
# Extract input key material (IKM) bytes
|
|
675
|
+
if isinstance(secret, SymmetricKeyValue):
|
|
676
|
+
ikm = secret.key_bytes
|
|
677
|
+
elif isinstance(secret, TensorValue):
|
|
678
|
+
ikm = secret.unwrap().tobytes()
|
|
679
|
+
else:
|
|
680
|
+
raise TypeError(
|
|
681
|
+
f"hkdf secret must be SymmetricKeyValue or TensorValue, "
|
|
682
|
+
f"got {type(secret).__name__}"
|
|
683
|
+
)
|
|
684
|
+
|
|
685
|
+
# Validate hash algorithm (currently only SHA-256 implemented)
|
|
686
|
+
if hash_algo != "sha256":
|
|
687
|
+
raise NotImplementedError(
|
|
688
|
+
f"HKDF with hash algorithm '{hash_algo}' is not yet implemented. "
|
|
689
|
+
f"Currently only 'sha256' is supported. "
|
|
690
|
+
f"Planned future support: sha512, sha3256, blake2b"
|
|
691
|
+
)
|
|
692
|
+
|
|
693
|
+
# Perform HKDF derivation using cryptography library
|
|
694
|
+
# Note: salt=None uses 32-byte all-zero salt (not random salt!)
|
|
695
|
+
# This is secure ONLY because ECDH outputs are already high-entropy (256-bit uniform)
|
|
696
|
+
# For low-entropy inputs or repeated derivations, a random salt would be required
|
|
697
|
+
hkdf = HKDF(
|
|
698
|
+
algorithm=hashes.SHA256(),
|
|
699
|
+
length=32, # Output length in bytes (AES-256 key = 32 bytes)
|
|
700
|
+
salt=None, # 32-byte zero salt (secure for high-entropy ECDH shared secrets)
|
|
701
|
+
info=info_bytes, # Context-specific binding for domain separation
|
|
702
|
+
)
|
|
703
|
+
|
|
704
|
+
derived_key = hkdf.derive(ikm)
|
|
705
|
+
|
|
706
|
+
# Return SymmetricKeyValue with composite suite name
|
|
707
|
+
# Format: "hkdf-{hash_algo}" to indicate derivation method and hash function
|
|
708
|
+
suite = f"hkdf-{hash_algo}"
|
|
709
|
+
return SymmetricKeyValue(suite=suite, key_bytes=derived_key)
|
|
710
|
+
|
|
711
|
+
|
|
617
712
|
@crypto.random_bytes_p.def_impl
|
|
618
713
|
def random_bytes_impl(interpreter: Interpreter, op: Operation) -> TensorValue:
|
|
619
714
|
"""Generate random bytes using os.urandom."""
|
mplang/v2/dialects/crypto.py
CHANGED
|
@@ -199,6 +199,9 @@ select_p = el.Primitive[el.Object]("crypto.select")
|
|
|
199
199
|
kem_keygen_p = el.Primitive[tuple[el.Object, el.Object]]("crypto.kem_keygen")
|
|
200
200
|
kem_derive_p = el.Primitive[el.Object]("crypto.kem_derive")
|
|
201
201
|
|
|
202
|
+
# HKDF (Key Derivation Function)
|
|
203
|
+
hkdf_p = el.Primitive[el.Object]("crypto.hkdf")
|
|
204
|
+
|
|
202
205
|
# Randomness
|
|
203
206
|
random_bytes_p = el.Primitive[el.Object]("crypto.random_bytes")
|
|
204
207
|
|
|
@@ -336,6 +339,41 @@ def _kem_derive_ae(
|
|
|
336
339
|
return SymmetricKeyType(suite)
|
|
337
340
|
|
|
338
341
|
|
|
342
|
+
@hkdf_p.def_abstract_eval
|
|
343
|
+
def _hkdf_ae(
|
|
344
|
+
secret: elt.BaseType, *, info: str, hash_algo: str = "sha256"
|
|
345
|
+
) -> SymmetricKeyType:
|
|
346
|
+
"""Abstract evaluation for HKDF key derivation.
|
|
347
|
+
|
|
348
|
+
Args:
|
|
349
|
+
secret: Input key material (SymmetricKeyType from kem_derive or TensorType[u8])
|
|
350
|
+
info: Context string for domain separation (required, non-empty, keyword-only)
|
|
351
|
+
hash_algo: Hash algorithm in lowercase without hyphens (e.g., "sha256", keyword-only)
|
|
352
|
+
|
|
353
|
+
Returns:
|
|
354
|
+
SymmetricKeyType with suite="hkdf-{hash_algo}"
|
|
355
|
+
|
|
356
|
+
Raises:
|
|
357
|
+
TypeError: If info or hash_algo is not a string
|
|
358
|
+
ValueError: If info is empty (required for domain separation per NIST)
|
|
359
|
+
"""
|
|
360
|
+
# Validate info and hash_algo at trace time
|
|
361
|
+
if not isinstance(info, str) or not info:
|
|
362
|
+
raise ValueError(
|
|
363
|
+
"HKDF requires non-empty 'info' parameter for domain separation. "
|
|
364
|
+
"The info string binds the derived key to a specific protocol/context. "
|
|
365
|
+
"Recommended format: 'namespace/component/purpose/version'"
|
|
366
|
+
)
|
|
367
|
+
if not isinstance(hash_algo, str) or not hash_algo:
|
|
368
|
+
raise TypeError("hash_algo must be a non-empty string")
|
|
369
|
+
|
|
370
|
+
# Normalize: lowercase, no hyphens
|
|
371
|
+
hash_algo_normalized = hash_algo.lower().replace("-", "").replace("_", "")
|
|
372
|
+
|
|
373
|
+
# Return SymmetricKeyType with composite suite indicating derivation method
|
|
374
|
+
return SymmetricKeyType(suite=f"hkdf-{hash_algo_normalized}")
|
|
375
|
+
|
|
376
|
+
|
|
339
377
|
@random_bytes_p.def_abstract_eval
|
|
340
378
|
def _random_bytes_ae(length: int) -> elt.TensorType:
|
|
341
379
|
return elt.TensorType(elt.u8, (length,))
|
|
@@ -472,6 +510,69 @@ def kem_derive(private_key: el.Object, public_key: el.Object) -> el.Object:
|
|
|
472
510
|
return kem_derive_p.bind(private_key, public_key)
|
|
473
511
|
|
|
474
512
|
|
|
513
|
+
def hkdf(secret: el.Object, info: str, *, hash_algo: str = "sha256") -> el.Object:
|
|
514
|
+
"""Derive a cryptographic key from input key material using HKDF.
|
|
515
|
+
|
|
516
|
+
HKDF (HMAC-based Key Derivation Function) is specified in RFC 5869 and
|
|
517
|
+
required by NIST SP 800-56C Rev.2 for deriving symmetric keys from
|
|
518
|
+
key agreement schemes like ECDH. Per NIST: "The shared secret output
|
|
519
|
+
from a key-agreement scheme SHALL NOT be used directly as a cryptographic
|
|
520
|
+
key. A key-derivation function (KDF) SHALL be used."
|
|
521
|
+
|
|
522
|
+
Args:
|
|
523
|
+
secret: Input key material (IKM). Accepts:
|
|
524
|
+
- SymmetricKeyValue: Typically from crypto.kem_derive (ECDH output)
|
|
525
|
+
- TensorType[u8, (N,)]: Raw bytes (N-byte secret)
|
|
526
|
+
info: Application-specific context string for domain separation.
|
|
527
|
+
REQUIRED and must be non-empty. Different info values produce
|
|
528
|
+
cryptographically independent keys even from the same secret.
|
|
529
|
+
Recommended format: "namespace/component/purpose/version"
|
|
530
|
+
Example: "mplang/device/tee/v2"
|
|
531
|
+
hash_algo: Hash function to use. Must be lowercase without hyphens.
|
|
532
|
+
Currently supported: "sha256" (default)
|
|
533
|
+
Future support planned: "sha512", "sha3256", "blake2b"
|
|
534
|
+
Default "sha256" provides 128-bit security level.
|
|
535
|
+
|
|
536
|
+
Returns:
|
|
537
|
+
SymmetricKeyValue with:
|
|
538
|
+
- suite: "hkdf-{hash_algo}" (e.g., "hkdf-sha256")
|
|
539
|
+
- key_bytes: 32-byte derived key suitable for AES-256-GCM
|
|
540
|
+
|
|
541
|
+
Security considerations:
|
|
542
|
+
- Output length: Fixed at 32 bytes (256 bits) for AES-256 keys
|
|
543
|
+
- Salt: Uses salt=None (acceptable for ECDH output per NIST guidance)
|
|
544
|
+
- Info: Provides protocol/context binding (domain separation)
|
|
545
|
+
- Deterministic: Same (secret, info, hash_algo) always produces same key
|
|
546
|
+
|
|
547
|
+
Raises:
|
|
548
|
+
ValueError:
|
|
549
|
+
- At abstract evaluation time if hash_algo is unsupported.
|
|
550
|
+
- At execution time if info is empty.
|
|
551
|
+
NotImplementedError:
|
|
552
|
+
- At execution time if hash_algo is not "sha256".
|
|
553
|
+
|
|
554
|
+
Examples:
|
|
555
|
+
>>> # Standard TEE session establishment
|
|
556
|
+
>>> sk_local, pk_local = crypto.kem_keygen("x25519")
|
|
557
|
+
>>> sk_remote, pk_remote = crypto.kem_keygen("x25519")
|
|
558
|
+
>>> # ECDH on both sides
|
|
559
|
+
>>> shared_local = crypto.kem_derive(sk_local, pk_remote)
|
|
560
|
+
>>> shared_remote = crypto.kem_derive(sk_remote, pk_local)
|
|
561
|
+
>>> # HKDF for domain separation
|
|
562
|
+
>>> sess_local = crypto.hkdf(shared_local, "mplang/device/tee/v2")
|
|
563
|
+
>>> sess_remote = crypto.hkdf(shared_remote, "mplang/device/tee/v2")
|
|
564
|
+
>>> # sess_local and sess_remote have identical key_bytes
|
|
565
|
+
>>> # but suite="hkdf-sha256" (not "x25519")
|
|
566
|
+
>>>
|
|
567
|
+
>>> # Derive multiple independent keys from one master secret
|
|
568
|
+
>>> master_secret = crypto.kem_derive(sk, pk)
|
|
569
|
+
>>> encryption_key = crypto.hkdf(master_secret, "app/encryption/v1")
|
|
570
|
+
>>> mac_key = crypto.hkdf(master_secret, "app/mac/v1")
|
|
571
|
+
>>> # encryption_key ≠ mac_key due to different info strings
|
|
572
|
+
"""
|
|
573
|
+
return hkdf_p.bind(secret, info=info, hash_algo=hash_algo)
|
|
574
|
+
|
|
575
|
+
|
|
475
576
|
def random_bytes(length: int) -> el.Object:
|
|
476
577
|
"""Generate cryptographically secure random bytes at runtime.
|
|
477
578
|
|
mplang/v2/libs/device/api.py
CHANGED
|
@@ -61,6 +61,9 @@ DEVICE_ATTR_NAME = "__device__"
|
|
|
61
61
|
# Default KEM suite for TEE session establishment
|
|
62
62
|
_TEE_KEM_SUITE: str = "x25519"
|
|
63
63
|
|
|
64
|
+
# HKDF info string for TEE session key derivation (domain separation)
|
|
65
|
+
_TEE_HKDF_INFO: str = "mplang/device/tee/v2"
|
|
66
|
+
|
|
64
67
|
# Global cache for TEE sessions (keyed by (frm_dev_id, to_dev_id))
|
|
65
68
|
# Each entry is (context_id, sess_frm, sess_tee) where context_id ensures
|
|
66
69
|
# sessions are not reused across different trace/interp contexts.
|
|
@@ -412,16 +415,24 @@ def _ensure_tee_session(
|
|
|
412
415
|
"""Ensure a TEE session (sess_frm at sender, sess_tee at TEE) exists.
|
|
413
416
|
|
|
414
417
|
Performs remote attestation and establishes an encrypted channel between
|
|
415
|
-
a PPU and a TEE device
|
|
416
|
-
|
|
418
|
+
a PPU and a TEE device using NIST SP 800-56C compliant key derivation.
|
|
419
|
+
Session keys are cached within the same execution context to avoid
|
|
420
|
+
repeated handshakes.
|
|
417
421
|
|
|
418
|
-
|
|
422
|
+
Protocol (ECDH + Remote Attestation + HKDF):
|
|
419
423
|
1. TEE generates keypair (sk, pk) and creates attestation quote binding pk
|
|
420
|
-
2. Quote is sent to
|
|
424
|
+
2. Quote is sent to sender (PPU) for verification
|
|
421
425
|
3. Sender verifies quote and extracts TEE's attested public key
|
|
422
|
-
4. Sender generates
|
|
423
|
-
5. Both sides derive shared secret using
|
|
424
|
-
6.
|
|
426
|
+
4. Sender generates ephemeral keypair and sends pk to TEE
|
|
427
|
+
5. Both sides derive ECDH shared secret using X25519
|
|
428
|
+
6. Both sides derive session keys from shared secret using HKDF-SHA256
|
|
429
|
+
with protocol-specific info string for domain separation
|
|
430
|
+
|
|
431
|
+
Security properties:
|
|
432
|
+
- Remote attestation: TEE identity is cryptographically verified
|
|
433
|
+
- Ephemeral keys: Perfect forward secrecy (keys not reused across sessions)
|
|
434
|
+
- HKDF derivation: NIST SP 800-56C compliant (shared secret not used directly)
|
|
435
|
+
- Domain separation: Info parameter binds keys to TEE protocol v2
|
|
425
436
|
|
|
426
437
|
Args:
|
|
427
438
|
frm_dev_id: Source device ID (PPU)
|
|
@@ -462,10 +473,18 @@ def _ensure_tee_session(
|
|
|
462
473
|
v_sk, v_pk = simp.pcall_static((frm_rank,), crypto.kem_keygen, _TEE_KEM_SUITE)
|
|
463
474
|
v_pk_at_tee = simp.shuffle_static(v_pk, {tee_rank: frm_rank})
|
|
464
475
|
|
|
465
|
-
# 5. Both sides derive shared secret
|
|
466
|
-
#
|
|
467
|
-
|
|
468
|
-
|
|
476
|
+
# 5. Both sides derive ECDH shared secret using X25519
|
|
477
|
+
# Note: kem_derive signature is (private_key, public_key) - suite is in key type
|
|
478
|
+
shared_frm = simp.pcall_static(
|
|
479
|
+
(frm_rank,), crypto.kem_derive, v_sk, tee_pk_at_sender
|
|
480
|
+
)
|
|
481
|
+
shared_tee = simp.pcall_static((tee_rank,), crypto.kem_derive, tee_sk, v_pk_at_tee)
|
|
482
|
+
|
|
483
|
+
# 6. Derive session keys using HKDF-SHA256 for domain separation
|
|
484
|
+
# Per NIST SP 800-56C: "shared secret SHALL NOT be used directly as a key"
|
|
485
|
+
# HKDF provides: uniform distribution + protocol-specific context binding
|
|
486
|
+
sess_frm = simp.pcall_static((frm_rank,), crypto.hkdf, shared_frm, _TEE_HKDF_INFO)
|
|
487
|
+
sess_tee = simp.pcall_static((tee_rank,), crypto.hkdf, shared_tee, _TEE_HKDF_INFO)
|
|
469
488
|
|
|
470
489
|
# Cache the session
|
|
471
490
|
_tee_session_cache[key] = (current_context_id, sess_frm, sess_tee)
|
|
@@ -82,7 +82,7 @@ mplang/v2/cli.py,sha256=QtiTFG418k26opRy4GhVV8fwFqRS11xTLH3xRCIIm6M,19665
|
|
|
82
82
|
mplang/v2/cli_guide.md,sha256=kyoCaqkvIJJ1vsvCyBu3qgOuRSb0txu9BDZoy9GU5S0,3617
|
|
83
83
|
mplang/v2/backends/__init__.py,sha256=H-4-jBEPWBZl6XT7AxBShRINnruF_f_2lB4iaiQoXME,1988
|
|
84
84
|
mplang/v2/backends/bfv_impl.py,sha256=cQPinze3c2xN4CmIIoXxZoIEhu9ynoGaXbdF95z_aTE,25709
|
|
85
|
-
mplang/v2/backends/crypto_impl.py,sha256
|
|
85
|
+
mplang/v2/backends/crypto_impl.py,sha256=tU0KdI34hnYvYujKUkiA1XYpvy4lo_MKpidt0NSIKlk,23205
|
|
86
86
|
mplang/v2/backends/field_impl.py,sha256=50sKGOlkUiaTj_IAola86uQeoi-fxV0o7G91BdTCWZA,14788
|
|
87
87
|
mplang/v2/backends/func_impl.py,sha256=R0662cC0gSSfkjuLyevJ_g4bJDJirY76LTFYqEimCkE,3585
|
|
88
88
|
mplang/v2/backends/phe_impl.py,sha256=r836e_qBHGrHhfnFail5IaUDzvS7bABjdEQmJmAtBVI,4127
|
|
@@ -106,7 +106,7 @@ mplang/v2/backends/simp_worker/ops.py,sha256=DMQCsKeoMtemy5ozsVZt2eoF8NZlhLeHZMD
|
|
|
106
106
|
mplang/v2/backends/simp_worker/state.py,sha256=eRUI7MP6gU8KPC9-H5fwcoAPKOsfW2ODWvpoKWbecMk,1554
|
|
107
107
|
mplang/v2/dialects/__init__.py,sha256=hvzAvz6_brfFyDGgKknoPdgh5EY033YNYwotuJK_zoA,1493
|
|
108
108
|
mplang/v2/dialects/bfv.py,sha256=XrE3FX9DHWqNzUVzY0tuwPvNVVRZYpD51JZIZF-q-l4,22350
|
|
109
|
-
mplang/v2/dialects/crypto.py,sha256=
|
|
109
|
+
mplang/v2/dialects/crypto.py,sha256=dH_DtoE3pGAKeOLPHxeyGtXC-nGwBsOs62TKikJEaq0,22197
|
|
110
110
|
mplang/v2/dialects/dtypes.py,sha256=bGM3Jna3BnvE4MPOurWrEmQegGPxd26z1HIWox1rj0U,12104
|
|
111
111
|
mplang/v2/dialects/field.py,sha256=6nBJg08k5WHb2o5msr8XAnxMQLpoTej55VQ7iSRnC4o,6380
|
|
112
112
|
mplang/v2/dialects/func.py,sha256=UlaMof4NEG28VOtiRL7zBRYgFbIX74YTqqgvozbils0,4375
|
|
@@ -138,7 +138,7 @@ mplang/v2/kernels/okvs_opt.cpp,sha256=d_HhvMdcebYsG2x7kYzjuFgmEsh9WKLH6SHee3375B
|
|
|
138
138
|
mplang/v2/kernels/py_kernels.py,sha256=FDsD86IHV-UBzxZLolhSOkrp24PuboHXeb1gBHLOfMo,12073
|
|
139
139
|
mplang/v2/libs/collective.py,sha256=pfXq9tmFUNKjeHhWMTjtzOi-m2Fn1lLru1G6txZVyic,10683
|
|
140
140
|
mplang/v2/libs/device/__init__.py,sha256=mXsSvXrWmlHu6Ch87Vcd85m4L_qdDkbSvJyHyuai2fc,1251
|
|
141
|
-
mplang/v2/libs/device/api.py,sha256=
|
|
141
|
+
mplang/v2/libs/device/api.py,sha256=d_Wbka8bxxXsRMW6zDhjzL9LPtChSk2-ryfi-c4Mqsk,28830
|
|
142
142
|
mplang/v2/libs/device/cluster.py,sha256=YUqYZ_IBS6rpV5ejUFP3kTxcTQHSyeDeuaJcsiFY_Js,12508
|
|
143
143
|
mplang/v2/libs/ml/__init__.py,sha256=xTxhC_YwHP32muUEFCEwOjc-3Ml-vmO48NNECU90zm4,787
|
|
144
144
|
mplang/v2/libs/ml/sgb.py,sha256=qoJww01EEbWo9nvwB5w-JZqx9BchcmhSrToypxV7fPg,60297
|
|
@@ -170,8 +170,8 @@ mplang/v2/runtime/dialect_state.py,sha256=HxO1i4kSOujS2tQzAF9-WmI3nChSaGgupf2_07
|
|
|
170
170
|
mplang/v2/runtime/interpreter.py,sha256=UzrM5oepka6H0YKRZncNXhsuwKVm4pliG5J92fFRZMI,32300
|
|
171
171
|
mplang/v2/runtime/object_store.py,sha256=yT6jtKG2GUEJVmpq3gnQ8mCMvUFYzgBciC5A-J5KRdk,5998
|
|
172
172
|
mplang/v2/runtime/value.py,sha256=CMOxElJP78v7pjasPhEpbxWbSgB2KsLbpPmzz0mQX0E,4317
|
|
173
|
-
mplang_nightly-0.1.
|
|
174
|
-
mplang_nightly-0.1.
|
|
175
|
-
mplang_nightly-0.1.
|
|
176
|
-
mplang_nightly-0.1.
|
|
177
|
-
mplang_nightly-0.1.
|
|
173
|
+
mplang_nightly-0.1.dev266.dist-info/METADATA,sha256=y4CgWHDl3wbczPz2lcTxnqXsTGFkPcuk3bGcnIQoAV0,16775
|
|
174
|
+
mplang_nightly-0.1.dev266.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
175
|
+
mplang_nightly-0.1.dev266.dist-info/entry_points.txt,sha256=mG1oJT-GAjQR834a62_QIWb7litzWPPyVnwFqm-rWuY,55
|
|
176
|
+
mplang_nightly-0.1.dev266.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
177
|
+
mplang_nightly-0.1.dev266.dist-info/RECORD,,
|
|
File without changes
|
{mplang_nightly-0.1.dev265.dist-info → mplang_nightly-0.1.dev266.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{mplang_nightly-0.1.dev265.dist-info → mplang_nightly-0.1.dev266.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|