3DSM 1.0
把许可声明、作者签名和几何指纹装进一个 .3dsm 文件,让已经分发出去的 3D 模型可以被独立验证与追溯。
.3dsm 是 3MF 的扩展容器(OPC/ZIP):3D/3dmodel.model 保持任何 3MF 工具可读,3D/share/manifest.json 承载许可、来源、指纹与签名。
- 打包 — 写入 3MF 核心元数据与 manifest
- 签名 — manifest 规范化后 Ed25519 签名,可选 RFC 3161 时间戳
- 指纹 — 球谐幅值谱 + 簇距直方图混合(默认),可仅凭公开几何复算
- 验证 — 验签 + 指纹比对,输出结构化证据报告
包名是
cdsm,分发名与导入名一致;格式名仍是3dsm,文件扩展名.3dsm。
快速开始
需要 Python 3.14+。
uv sync
from cdsm import DSM
DSM.keygen("author_priv.pem", "author_pub.pem")
dsm = DSM(
license_id="CC-BY-NC-ND-4.0",
author="Example Author",
model_id="sha256:example0001",
private_key="author_priv.pem",
public_key="author_pub.pem",
)
dsm.pack("cube.model", "cube.3dsm", title="Unit Cube")
report = dsm.verify("cube.3dsm")
dsm.export("cube.3dsm", "cube.obj")
print(report["manifest_valid"], report["manifest_trust"], report["similarity_score"])
# True out_of_band 1.0
pack() 的第一个参数可以是 Mesh、.model 文件、.obj / .stl / .ply,或 model XML 文本。
许可与 policy
license_id 使用 SPDX 标识符。内置常用子集,未显式传参时自动推导 derivative_policy:
| 许可 | 衍生 | 商用 | 署名 |
|---|---|---|---|
CC0-1.0、Unlicense |
✓ | ✓ | – |
MIT、Apache-2.0、BSD-3-Clause、MPL-2.0 |
✓ | ✓ | ✓ |
CC-BY-4.0、CC-BY-SA-4.0 |
✓ | ✓ | ✓ |
CC-BY-ND-4.0 |
– | ✓ | ✓ |
CC-BY-NC-4.0、CC-BY-NC-SA-4.0 |
✓ | – | ✓ |
CC-BY-NC-ND-4.0 |
– | – | ✓ |
显式传入 derivative_allowed / commercial_use / attribution_required 时以显式值为准。未知标识符按保守策略(禁止衍生、禁止商用、要求署名)并给出警告;LicenseRef-* 不生成 license_url。
导出到 OBJ/STL/PLY 时,政策冲突只告警、不阻断,许可与署名会写入目标格式的注释;这与规范 §7.3 的声明性定位一致,不阻断不等于授权。
uv run dsm licenses
完整流程(造模型 → 打包 → 验证 → 变形后复验):
uv run python examples/demo.py
uv run pytest -q
.3dsm 里有什么
cube.3dsm
├── [Content_Types].xml # OPC 内容类型
├── _rels/.rels # StartPart 指向 /3D/3dmodel.model
├── 3D/3dmodel.model # 3MF 核心模型 + preserve 元数据
└── 3D/share/manifest.json # 许可、来源、指纹、签名
manifest 主要字段:
| 字段 | 说明 |
|---|---|
format |
固定 3dsm/1.0 |
license / license_url |
SPDX 标识符及其链接 |
derivative_policy |
allowed、commercial_use、attribution_required、trace_threshold、lower_bound |
origin |
model_id、author,可选 title |
fingerprint |
algorithm、value(hy1: / sh1: / oh1: + base64),可选 watermark_id |
distribution_id |
可选,分发记录标识 |
signature |
algorithm、value、public_key,可选 timestamp_token |
验证报告
{
"report_version": "3dsm-verify/1.0",
"manifest_valid": true,
"manifest_trust": "out_of_band",
"signature_reason": "ok",
"fingerprint_algorithm": "hybrid-v1",
"timestamp": { "status": "absent" },
"similarity_score": 1.0,
"trace_threshold": 0.8,
"threshold_met": true,
"evidence_tendency": "derivative_suspected",
"watermark_result": "not_attempted",
"distribution_id": null,
"license_fields": {
"license": "CC-BY-NC-ND-4.0",
"derivative_allowed": false,
"commercial_use": false,
"attribution_required": true
},
"disclaimer": "This report contains evidence only and does not constitute a legal determination."
}
| 字段 | 取值 |
|---|---|
manifest_valid |
签名是否通过 |
manifest_trust |
out_of_band(带外可信公钥)/ embedded_hint(内嵌公钥,仅提示)/ none |
fingerprint_algorithm |
复算使用的指纹算法,取自参考 manifest |
timestamp |
{"status": "absent"},或 RFC 3161 校验结果 |
similarity_score |
与参考指纹的余弦相似度 |
evidence_tendency |
derivative_suspected / inconclusive / likely_independent |
报告只提供证据,不构成法律判定。
命令行
uv run dsm keygen --private author_priv.pem --public author_pub.pem
uv run dsm pack --model cube.model --key author_priv.pem --out cube.3dsm --license CC-BY-NC-ND-4.0 --author "Example Author" --model-id sha256:example0001
uv run dsm verify --candidate cube.3dsm --pub author_pub.pem --out report.json
uv run dsm inspect --path cube.3dsm
uv run dsm export --candidate cube.3dsm --out cube.obj --pub author_pub.pem
uv run dsm licenses
API
| 用法 | 说明 |
|---|---|
DSM.keygen(priv, pub) |
生成 Ed25519 密钥对 PEM |
dsm.pack(source, output, **overrides) |
指纹 → manifest → 签名 → 打包,返回已签名 manifest |
dsm.verify(candidate, *, report_path=None, ...) |
返回报告字典,可选落盘 |
dsm.inspect(path) |
列出部件与 manifest |
dsm.fingerprint(source) |
计算指纹字符串 |
dsm.compare(a, b) |
两个模型的指纹相似度 |
dsm.export(source, output, purpose=..., is_derivative=...) |
导出为 OBJ/STL/PLY,返回政策判定与告警 |
dsm.use_keys(priv, pub) |
替换密钥,返回自身 |
项目结构
src/cdsm/ api.py 封装 · core.py 签名与加密 · fingerprint.py 指纹
packager.py 容器 · formats.py OBJ/STL/PLY · export.py 导出
licenses.py 许可子集 · timestamp.py RFC 3161 · verifier.py 验证
watermark.py 水印 provider · cli.py 命令行
docs/ 规范草案(中/英)+ 技术实现指南
examples/ demo.py 端到端示例
tests/ pytest 用例
文档
许可
本仓库代码以 Apache-2.0 发布,版权与归属见 NOTICE。.3dsm 文件内 manifest.license 声明的是模型内容的许可,与本项目代码的许可相互独立。
已知边界
- 指纹默认
hybrid-v1(球谐幅值谱 + 簇距直方图),另有spherical-harmonics-v1与onion-hash-v1可选;均只依赖公开几何,安全性来自分发记录与阈值。 - 未附加时间戳时报告标注
timestamp: absent;RFC 3161 需要uv sync --extra timestamp。 - Secure Content 只提供 AES-256-GCM / RSA-OAEP 原语,密钥释放策略由部署方决定。
- FuncMark 只在实现指南中定义接口,未实现。
- OBJ/PLY 用注释携带许可与署名;STL 只有 80 字节二进制头,信息可能被截断。
Metadata
Release files for cdsm 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| cdsm-0.1.0.tar.gz | 28.2 kB | Without provenance | Details for cdsm-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| cdsm-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for cdsm-0.1.0-py3-none-any.whl |
Total release size: 61.5 kB
Release files / cdsm-0.1.0.tar.gz
| Download URL | cdsm-0.1.0.tar.gz |
|---|---|
| Size | 28.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
07599cdb1338d47666e979835234308c174f1466643b1c546af873a6777ec306
|
|
BLAKE2b-256 checksum How to use checksums |
03b41d0ae89d50b012f3dea8d6c87b4dfcb00ebcde0206fc3084d6dfc1da1862
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / cdsm-0.1.0-py3-none-any.whl
| Download URL | cdsm-0.1.0-py3-none-any.whl |
|---|---|
| Size | 33.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
efda3cccca6c934f2d1712abaa6aa47f0eed50d450e40f3e73f071a843c9d359
|
|
BLAKE2b-256 checksum How to use checksums |
87dd975e5500fde57f77ec5e7bde49c85632741f74bdb3308f5712e3400dc7f9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for cdsm 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.