Skip to content

Commit ebd1519

Browse files
[crypto] ML-DSA-87: Hashing of the keygen seed Xi
ML-DSA keygen is parametrized by a seed Xi that needs to be hash in order to derived the public and secret keys. Signed-off-by: Andrea Caforio <andrea.caforio@lowrisc.org>
1 parent f31f484 commit ebd1519

4 files changed

Lines changed: 164 additions & 0 deletions

File tree

sw/otbn/crypto/mldsa87/keygen/mldsa87_keygen_ops.s

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
.globl sample_s
88
.globl compute_t
99
.globl encode_t
10+
.globl hash_seed
1011

1112
.text
1213

@@ -317,3 +318,68 @@ encode_t:
317318
/* End of loop */
318319

319320
ret
321+
322+
/**
323+
* Hash the seed Xi.
324+
*
325+
* ML-DSA keygen is parametrized by a 32-byte seed Xi (passed as a 34-byte
326+
* value) that is hashed to create RHO, RHO_PRIME and K, i.e.,
327+
*
328+
* RHO, RHO_PRIME, K = Shake256(Xi),
329+
*
330+
* where RHO is a 32-byte unshared value, RHO_PRIME is a 64-byte Boolean-shared
331+
* value and K is a 32-byte Boolean-shared value.
332+
*
333+
* Xi is assumed to be passed as a 34-byte value in a 64-byte region with bytes
334+
* 32 and 33 of both shares set to 0.
335+
*
336+
* @param[in] x2: DMEM address of the first Boolean share of Xi.
337+
* @param[in] x3: DMEM address of the second Boolean share of Xi.
338+
* @param[in] x4: DMEM address of RHO.
339+
* @param[in] x5: DMEM address of the first Boolean share of RHO_PRIME.
340+
* @param[in] x6: DMEM address of the second Boolean share of RHO_PRIME.
341+
* @param[in] x7: DMEM address of the first Boolean share of K.
342+
* @param[in] x8: DMEM address of the second Boolean share of K.
343+
*/
344+
hash_seed:
345+
/* Xi[32] = K = 8, Xi[33] = L = 7. */
346+
li x9, 0x00000708
347+
sw x9, 32(x2)
348+
349+
/* Squeeze buffer WDR pointers. */
350+
addi x9, x0, 29
351+
addi x10, x0, 30
352+
353+
jal x1, xof_shake256_init
354+
355+
/* Absorb the 34-byte Boolean shared seed value Xi. */
356+
addi x20, x0, 34
357+
addi x21, x2, 0
358+
addi x22, x3, 0
359+
jal x1, xof_absorb
360+
jal x1, xof_process
361+
362+
/* Squeeze the 32-byte unshared value RHO. */
363+
jal x1, xof_squeeze32
364+
bn.xor w29, w29, w30 /* unmask */
365+
bn.sid x9, 0(x4)
366+
367+
/* Squeeze the 64-byte Boolean-shared value RHO_PRIME. */
368+
jal x1, xof_squeeze32
369+
bn.sid x9, 0(x5)
370+
bn.xor w31, w31, w31 /* dummy */
371+
bn.sid x10, 0(x6)
372+
jal x1, xof_squeeze32
373+
bn.sid x9, 32(x5)
374+
bn.xor w31, w31, w31 /* dummy */
375+
bn.sid x10, 32(x6)
376+
377+
/* Squeeze the 32-byte Boolean-shared value K. */
378+
jal x1, xof_squeeze32
379+
bn.sid x9, 0(x7)
380+
bn.xor w31, w31, w31 /* dummy */
381+
bn.sid x10, 0(x8)
382+
383+
jal x1, xof_finish
384+
385+
ret

sw/otbn/crypto/mldsa87/keygen/tests/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ unit_tests = [
3434
"mldsa87_keygen_sample_s_test",
3535
"mldsa87_keygen_compute_t_test",
3636
"mldsa87_keygen_encode_t_test",
37+
"mldsa87_keygen_hash_seed_test",
3738
]
3839

3940
[
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright lowRISC contributors (OpenTitan project).
2+
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
// NIST ACVP ML-DSA-87 keygen vector #51 (first ML-DSA-87 vector):
6+
// https://github.com/usnistgov/ACVP-Server/blob/master/gen-val/json-files/ML-DSA-keyGen-FIPS204
7+
8+
{
9+
"entrypoint": "main",
10+
"input": {
11+
"dmem": {
12+
// Xi
13+
"_hash_seed_xi_share0": "0x7bcbfc40c22b8e76a5dd9f8927691d12305635a63b771687cd591792bb2f05f7",
14+
"_hash_seed_xi_share1": "0x0000000000000000000000000000000000000000000000000000000000000000"
15+
}
16+
},
17+
"output": {
18+
"dmem": {
19+
// RHO
20+
"_hash_seed_rho": "0xd937df8c3fe571dcc9de94cd892d91cfcdb5e640a21935a26e75f5de92f3df18",
21+
// RHO_PRIME
22+
"_hash_seed_rho_prime_share0": "0x3af649807ca2405382e16fc376486871f8478741dcb502773f43b3ff7910a4892f75a52f1205580933491c0c9434133ea4660011c521c5df9cf9b54bb701a885",
23+
// K
24+
"_hash_seed_k_share0": "0xd24ab993ed9fb49815e9ea7a168ae2a07c538064017431e12b26d55584d307d7",
25+
}
26+
}
27+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/* Copyright lowRISC contributors (OpenTitan project). */
2+
/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */
3+
/* SPDX-License-Identifier: Apache-2.0 */
4+
5+
/* Verify that keygen seed Xi hash is correctly hashed. */
6+
7+
.section .text.start
8+
9+
main:
10+
la x31, _stack
11+
bn.xor w31, w31, w31
12+
13+
la x2, _params
14+
bn.lid x0, 0(x2)
15+
bn.wsrw MOD, w0
16+
17+
la x2, _hash_seed_xi_share0
18+
la x3, _hash_seed_xi_share1
19+
la x4, _hash_seed_rho
20+
la x5, _hash_seed_rho_prime_share0
21+
la x6, _hash_seed_rho_prime_share1
22+
la x7, _hash_seed_k_share0
23+
la x8, _hash_seed_k_share1
24+
jal x1, hash_seed
25+
26+
la x20, _hash_seed_rho_prime_share0
27+
la x21, _hash_seed_rho_prime_share1
28+
addi x22, x0, 2
29+
jal x1, unmask_boolean
30+
31+
la x20, _hash_seed_k_share0
32+
la x21, _hash_seed_k_share1
33+
addi x22, x0, 1
34+
jal x1, unmask_boolean
35+
36+
ecall
37+
38+
.data
39+
.balign 32
40+
41+
_hash_seed_xi_share0:
42+
.zero 34
43+
.zero 30 /* Padding */
44+
_hash_seed_xi_share1:
45+
.zero 34
46+
.zero 30 /* Padding */
47+
48+
_hash_seed_rho:
49+
.zero 32
50+
_hash_seed_rho_prime_share0:
51+
.zero 64
52+
_hash_seed_rho_prime_share1:
53+
.zero 64
54+
_hash_seed_k_share0:
55+
.zero 32
56+
_hash_seed_k_share1:
57+
.zero 32
58+
59+
_params:
60+
.word 0x007fe001 /* q */
61+
.word 0xfc7fdfff /* mu */
62+
.word 0x0000a3fa /* n^-1 * R^3 mod q */
63+
.word 0x00000000
64+
.word 0x00000000
65+
.word 0x00000000
66+
.word 0x00000000
67+
.word 0x00000000
68+
69+
_stack:
70+
.zero 256

0 commit comments

Comments
 (0)