Skip to content

Commit 5f32539

Browse files
authored
Merge pull request #16 from tomato42/pkcs-files
Import/Export to IETF file formats
2 parents 22f0d83 + 6ab94bd commit 5f32539

File tree

6 files changed

+1555
-1
lines changed

6 files changed

+1555
-1
lines changed

.github/workflows/ci.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,22 @@ jobs:
4343
- name: py3.12
4444
os: ubuntu-latest
4545
python-version: "3.12"
46+
- name: py3.9 with ecdsa
47+
os: ubuntu-latest
48+
python-version: "3.9"
49+
opt-deps: ['ecdsa']
50+
- name: py3.10 with ecdsa
51+
os: ubuntu-latest
52+
python-version: "3.10"
53+
opt-deps: ['ecdsa']
54+
- name: py3.11 with ecdsa
55+
os: ubuntu-latest
56+
python-version: "3.11"
57+
opt-deps: ['ecdsa']
58+
- name: py3.12 with ecdsa
59+
os: ubuntu-latest
60+
python-version: "3.12"
61+
opt-deps: ['ecdsa']
4662
steps:
4763
- uses: actions/checkout@v4
4864
with:
@@ -66,6 +82,10 @@ jobs:
6682
- name: Install build dependencies
6783
run: |
6884
pip install -r requirements.txt
85+
- name: Install ecdsa
86+
if: ${{ contains(matrix.opt-deps, 'ecdsa') }}
87+
run: |
88+
pip install ecdsa
6989
- name: Display installed python package versions
7090
run: |
7191
pip list || :

pyproject.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ classifiers = [
1414
]
1515
license = "MIT"
1616

17+
[project.optional-dependencies]
18+
pkcs = [
19+
"ecdsa>=0.19.1",
20+
]
21+
1722
[project.urls]
1823
Homepage = "https://github.com/GiacomoPope/dilithium-py"
1924
Issues = "https://github.com/GiacomoPope/dilithium-py/issues"

src/dilithium_py/ml_dsa/default_parameters.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"eta": 2, # Private key range
1212
"omega": 80, # Max number of ones in hint
1313
"c_tilde_bytes": 32,
14+
"oid": (2, 16, 840, 1, 101, 3, 4, 3, 17),
1415
},
1516
"ML_DSA_65": {
1617
"d": 13, # number of bits dropped from t
@@ -22,6 +23,7 @@
2223
"eta": 4, # Private key range
2324
"omega": 55, # Max number of ones in hint
2425
"c_tilde_bytes": 48,
26+
"oid": (2, 16, 840, 1, 101, 3, 4, 3, 18),
2527
},
2628
"ML_DSA_87": {
2729
"d": 13, # number of bits dropped from t
@@ -33,6 +35,7 @@
3335
"eta": 2, # Private key range
3436
"omega": 75, # Max number of ones in hint
3537
"c_tilde_bytes": 64,
38+
"oid": (2, 16, 840, 1, 101, 3, 4, 3, 19),
3639
},
3740
}
3841

src/dilithium_py/ml_dsa/ml_dsa.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def __init__(self, parameter_set):
2222

2323
self.M = ModuleDilithium()
2424
self.R = self.M.ring
25+
self.oid = parameter_set["oid"] if "oid" in parameter_set else None
2526

2627
# Use system randomness by default, for deterministic randomness
2728
# use the method `set_drbg_seed()`
@@ -123,11 +124,26 @@ def _pack_h(self, h):
123124
def _pack_sig(self, c_tilde, z, h):
124125
return c_tilde + z.bit_pack_z(self.gamma_1) + self._pack_h(h)
125126

127+
def _pk_size(self):
128+
return 32 + 32 * self.k * 10
129+
126130
def _unpack_pk(self, pk_bytes):
131+
if len(pk_bytes) != self._pk_size():
132+
raise ValueError("PK packed bytes is of the wrong length")
127133
rho, t1_bytes = pk_bytes[:32], pk_bytes[32:]
128134
t1 = self.M.bit_unpack_t1(t1_bytes, self.k, 1)
129135
return rho, t1
130136

137+
def _sk_size(self):
138+
if self.eta == 2:
139+
s_bytes = 96
140+
else:
141+
s_bytes = 128
142+
s1_len = s_bytes * self.l
143+
s2_len = s_bytes * self.k
144+
t0_len = 416 * self.k
145+
return 2 * 32 + 64 + s1_len + s2_len + t0_len
146+
131147
def _unpack_sk(self, sk_bytes):
132148
if self.eta == 2:
133149
s_bytes = 96
@@ -136,7 +152,7 @@ def _unpack_sk(self, sk_bytes):
136152
s1_len = s_bytes * self.l
137153
s2_len = s_bytes * self.k
138154
t0_len = 416 * self.k
139-
if len(sk_bytes) != 2 * 32 + 64 + s1_len + s2_len + t0_len:
155+
if len(sk_bytes) != self._sk_size():
140156
raise ValueError("SK packed bytes is of the wrong length")
141157

142158
# Split bytes between seeds and vectors
@@ -404,6 +420,11 @@ def prehash_external_mu(self, pk_bytes, m, ctx=b""):
404420
raise ValueError(
405421
f"ctx bytes must have length at most 255, ctx has length {len(ctx) = }"
406422
)
423+
if len(pk_bytes) != self._pk_size():
424+
raise ValueError(
425+
f"Public key size doesn't match this ML-DSA object parameters,"
426+
f"received {len(pk_bytes) = }, expected: {self._pk_size()}"
427+
)
407428

408429
# Format the message using the context
409430
m_prime = bytes([0]) + bytes([len(ctx)]) + ctx + m

0 commit comments

Comments
 (0)