Home | History | Annotate | Line # | Download | only in dist
      1  1.2  christos /*	$NetBSD: libcrux-mlkem-mldsa.c,v 1.2 2026/09/21 23:01:54 christos Exp $	*/
      2  1.1  christos /* $OpenBSD: libcrux-mlkem-mldsa.c,v 1.1 2026/06/14 03:59:34 djm Exp $ */
      3  1.2  christos 
      4  1.1  christos /*
      5  1.1  christos  * Copyright (c) 2026 Damien Miller <djm (at) mindrot.org>
      6  1.1  christos  *
      7  1.1  christos  * Permission to use, copy, modify, and distribute this software for any
      8  1.1  christos  * purpose with or without fee is hereby granted, provided that the above
      9  1.1  christos  * copyright notice and this permission notice appear in all copies.
     10  1.1  christos  *
     11  1.1  christos  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     12  1.1  christos  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     13  1.1  christos  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     14  1.1  christos  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     15  1.1  christos  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     16  1.1  christos  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     17  1.1  christos  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     18  1.1  christos  */
     19  1.2  christos #include "includes.h"
     20  1.2  christos __RCSID("$NetBSD: libcrux-mlkem-mldsa.c,v 1.2 2026/09/21 23:01:54 christos Exp $");
     21  1.1  christos 
     22  1.1  christos #include <sys/types.h>
     23  1.1  christos #include <stdint.h>
     24  1.1  christos #include <stdlib.h>
     25  1.1  christos #include <stdbool.h>
     26  1.1  christos #include <string.h>
     27  1.1  christos 
     28  1.1  christos #include "log.h"
     29  1.1  christos #include "crypto_api.h"
     30  1.1  christos #include "libcrux_internal.h"
     31  1.1  christos 
     32  1.1  christos /* ML-KEM 768 */
     33  1.1  christos 
     34  1.1  christos int
     35  1.1  christos crypto_kem_mlkem768_keypair(uint8_t pk[crypto_kem_mlkem768_PUBLICKEYBYTES],
     36  1.1  christos     uint8_t sk[crypto_kem_mlkem768_SECRETKEYBYTES])
     37  1.1  christos {
     38  1.1  christos 	uint8_t rnd[crypto_kem_mlkem768_KEYPAIRSEEDBYTES];
     39  1.1  christos 	int r;
     40  1.1  christos 
     41  1.1  christos 	arc4random_buf(rnd, sizeof(rnd));
     42  1.1  christos 	r = crypto_kem_mlkem768_keypair_seeded(pk, sk, rnd);
     43  1.1  christos 	explicit_bzero(rnd, sizeof(rnd));
     44  1.1  christos 	return r;
     45  1.1  christos }
     46  1.1  christos 
     47  1.1  christos int
     48  1.1  christos crypto_kem_mlkem768_keypair_seeded(uint8_t pk[crypto_kem_mlkem768_PUBLICKEYBYTES],
     49  1.1  christos     uint8_t sk[crypto_kem_mlkem768_SECRETKEYBYTES],
     50  1.1  christos     const uint8_t seed[crypto_kem_mlkem768_KEYPAIRSEEDBYTES])
     51  1.1  christos {
     52  1.1  christos 	libcrux_mlkem768_keypair keypair;
     53  1.1  christos 	libcrux_mlkem768_keypair_rnd rnd;
     54  1.1  christos 
     55  1.1  christos 	memcpy(rnd.data, seed, sizeof(rnd.data));
     56  1.1  christos 	keypair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(rnd);
     57  1.1  christos 	memcpy(pk, keypair.pk.data, crypto_kem_mlkem768_PUBLICKEYBYTES);
     58  1.1  christos 	memcpy(sk, keypair.sk.data, crypto_kem_mlkem768_SECRETKEYBYTES);
     59  1.1  christos 
     60  1.1  christos 	explicit_bzero(&keypair, sizeof(keypair));
     61  1.1  christos 	explicit_bzero(&rnd, sizeof(rnd));
     62  1.1  christos 	return 0;
     63  1.1  christos }
     64  1.1  christos 
     65  1.1  christos int
     66  1.1  christos crypto_kem_mlkem768_enc(uint8_t ct[crypto_kem_mlkem768_CIPHERTEXTBYTES],
     67  1.1  christos     uint8_t shared_secret[crypto_kem_mlkem768_BYTES],
     68  1.1  christos     const uint8_t pk[crypto_kem_mlkem768_PUBLICKEYBYTES])
     69  1.1  christos {
     70  1.1  christos 	uint8_t rnd[crypto_kem_mlkem768_ENCSEEDBYTES];
     71  1.1  christos 	int r;
     72  1.1  christos 
     73  1.1  christos 	arc4random_buf(rnd, sizeof(rnd));
     74  1.1  christos 	r = crypto_kem_mlkem768_enc_seeded(ct, shared_secret, pk, rnd);
     75  1.1  christos 	explicit_bzero(rnd, sizeof(rnd));
     76  1.1  christos 	return r;
     77  1.1  christos }
     78  1.1  christos 
     79  1.1  christos int
     80  1.1  christos crypto_kem_mlkem768_enc_seeded(uint8_t ct[crypto_kem_mlkem768_CIPHERTEXTBYTES],
     81  1.1  christos     uint8_t shared_secret[crypto_kem_mlkem768_BYTES],
     82  1.1  christos     const uint8_t pk[crypto_kem_mlkem768_PUBLICKEYBYTES],
     83  1.1  christos     const uint8_t seed[crypto_kem_mlkem768_ENCSEEDBYTES])
     84  1.1  christos {
     85  1.1  christos 	libcrux_mlkem768_enc_result enc;
     86  1.1  christos 	libcrux_mlkem768_pk pk_internal;
     87  1.1  christos 	libcrux_mlkem768_enc_rnd rnd;
     88  1.1  christos 
     89  1.1  christos 	memcpy(pk_internal.data, pk, crypto_kem_mlkem768_PUBLICKEYBYTES);
     90  1.1  christos 	if (!libcrux_ml_kem_mlkem768_portable_validate_public_key(&pk_internal))
     91  1.1  christos 		return -1;
     92  1.1  christos 	memcpy(rnd.data, seed, sizeof(rnd.data));
     93  1.1  christos 	enc = libcrux_ml_kem_mlkem768_portable_encapsulate(&pk_internal, rnd);
     94  1.1  christos 	memcpy(ct, enc.fst.data, crypto_kem_mlkem768_CIPHERTEXTBYTES);
     95  1.1  christos 	memcpy(shared_secret, enc.snd.data, crypto_kem_mlkem768_BYTES);
     96  1.1  christos 
     97  1.1  christos 	explicit_bzero(&enc, sizeof(enc));
     98  1.1  christos 	explicit_bzero(&rnd, sizeof(rnd));
     99  1.1  christos 	return 0;
    100  1.1  christos }
    101  1.1  christos 
    102  1.1  christos int
    103  1.1  christos crypto_kem_mlkem768_dec(uint8_t shared_secret[crypto_kem_mlkem768_BYTES],
    104  1.1  christos     const uint8_t ct[crypto_kem_mlkem768_CIPHERTEXTBYTES],
    105  1.1  christos     const uint8_t sk[crypto_kem_mlkem768_SECRETKEYBYTES])
    106  1.1  christos {
    107  1.1  christos 	libcrux_mlkem768_sk sk_internal;
    108  1.1  christos 	libcrux_mlkem768_ciphertext ct_internal;
    109  1.1  christos 	libcrux_mlkem768_dec_result shared_secret_internal;
    110  1.1  christos 
    111  1.1  christos 	memcpy(sk_internal.data, sk, crypto_kem_mlkem768_SECRETKEYBYTES);
    112  1.1  christos 	memcpy(ct_internal.data, ct, crypto_kem_mlkem768_CIPHERTEXTBYTES);
    113  1.1  christos 	shared_secret_internal = libcrux_ml_kem_mlkem768_portable_decapsulate(
    114  1.1  christos 	    &sk_internal, &ct_internal);
    115  1.1  christos 	memcpy(shared_secret, shared_secret_internal.data,
    116  1.1  christos 	    crypto_kem_mlkem768_BYTES);
    117  1.1  christos 
    118  1.1  christos 	explicit_bzero(&sk_internal, sizeof(sk_internal));
    119  1.1  christos 	explicit_bzero(&shared_secret_internal, sizeof(shared_secret_internal));
    120  1.1  christos 	return 0;
    121  1.1  christos }
    122  1.1  christos 
    123  1.1  christos /* ML-DSA 44 */
    124  1.1  christos 
    125  1.1  christos int
    126  1.1  christos crypto_sign_mldsa44_keypair(uint8_t pk[MLDSA44_PUBLICKEYBYTES],
    127  1.1  christos     uint8_t sk[MLDSA44_SECRETKEYBYTES])
    128  1.1  christos {
    129  1.1  christos 	uint8_t rnd[MLDSA44_SEEDBYTES];
    130  1.1  christos 	int r;
    131  1.1  christos 
    132  1.1  christos 	arc4random_buf(rnd, sizeof(rnd));
    133  1.1  christos 	r = crypto_sign_mldsa44_keypair_seeded(pk, sk, rnd);
    134  1.1  christos 	explicit_bzero(rnd, sizeof(rnd));
    135  1.1  christos 	return r;
    136  1.1  christos }
    137  1.1  christos 
    138  1.1  christos int
    139  1.1  christos crypto_sign_mldsa44_keypair_seeded(uint8_t pk[MLDSA44_PUBLICKEYBYTES],
    140  1.1  christos     uint8_t sk[MLDSA44_SECRETKEYBYTES], const uint8_t seed[MLDSA44_SEEDBYTES])
    141  1.1  christos {
    142  1.1  christos 	libcrux_mldsa44_keypair_rnd rnd;
    143  1.1  christos 	libcrux_mldsa44_keypair keypair;
    144  1.1  christos 
    145  1.1  christos 	memcpy(rnd.data, seed, sizeof(rnd.data));
    146  1.1  christos 	keypair = libcrux_ml_dsa_ml_dsa_44_portable_generate_key_pair(rnd);
    147  1.1  christos 	memcpy(pk, keypair.verification_key.data, MLDSA44_PUBLICKEYBYTES);
    148  1.1  christos 	memcpy(sk, keypair.signing_key.data, MLDSA44_SECRETKEYBYTES);
    149  1.1  christos 
    150  1.1  christos 	explicit_bzero(&keypair, sizeof(keypair));
    151  1.1  christos 	explicit_bzero(&rnd, sizeof(rnd));
    152  1.1  christos 	return 0;
    153  1.1  christos }
    154  1.1  christos 
    155  1.1  christos int
    156  1.1  christos crypto_sign_mldsa44(uint8_t sig[MLDSA44_SIGBYTES],
    157  1.1  christos     const uint8_t *msg, size_t msglen,
    158  1.1  christos     const uint8_t *ctx, size_t ctxlen,
    159  1.1  christos     const uint8_t sk[MLDSA44_SECRETKEYBYTES])
    160  1.1  christos {
    161  1.1  christos 	uint8_t rnd[MLDSA44_SEEDBYTES];
    162  1.1  christos 	int r;
    163  1.1  christos 
    164  1.1  christos 	arc4random_buf(rnd, sizeof(rnd));
    165  1.1  christos 	r = crypto_sign_mldsa44_seeded(sig, msg, msglen, ctx, ctxlen, sk, rnd);
    166  1.1  christos 	explicit_bzero(rnd, sizeof(rnd));
    167  1.1  christos 	return r;
    168  1.1  christos }
    169  1.1  christos 
    170  1.1  christos int
    171  1.1  christos crypto_sign_mldsa44_seeded(uint8_t sig[MLDSA44_SIGBYTES],
    172  1.1  christos     const uint8_t *msg, size_t msglen,
    173  1.1  christos     const uint8_t *ctx, size_t ctxlen,
    174  1.1  christos     const uint8_t sk[MLDSA44_SECRETKEYBYTES],
    175  1.1  christos     const uint8_t seed[MLDSA44_SEEDBYTES])
    176  1.1  christos {
    177  1.1  christos 	libcrux_mldsa44_sign_rnd rnd;
    178  1.1  christos 	libcrux_mldsa44_sk sk_internal;
    179  1.1  christos 	libcrux_mldsa44_message message = { msg, msglen };
    180  1.1  christos 	libcrux_mldsa44_message context = { ctx, ctxlen };
    181  1.1  christos 	libcrux_mldsa44_sign_result res;
    182  1.1  christos 	int r = -1;
    183  1.1  christos 
    184  1.1  christos 	memcpy(sk_internal.data, sk, MLDSA44_SECRETKEYBYTES);
    185  1.1  christos 	memcpy(rnd.data, seed, sizeof(rnd.data));
    186  1.1  christos 	res = libcrux_ml_dsa_ml_dsa_44_portable_sign(&sk_internal,
    187  1.1  christos 	    message, context, rnd);
    188  1.1  christos 	if (res.tag == LIBCRUX_RESULT_OK) {
    189  1.1  christos 		memcpy(sig, res.val.case_Ok.data, MLDSA44_SIGBYTES);
    190  1.1  christos 		r = 0;
    191  1.1  christos 	}
    192  1.1  christos 
    193  1.1  christos 	explicit_bzero(&sk_internal, sizeof(sk_internal));
    194  1.1  christos 	explicit_bzero(&res, sizeof(res));
    195  1.1  christos 	explicit_bzero(&rnd, sizeof(rnd));
    196  1.1  christos 	return r;
    197  1.1  christos }
    198  1.1  christos 
    199  1.1  christos int
    200  1.1  christos crypto_sign_mldsa44_verify(const uint8_t sig[MLDSA44_SIGBYTES],
    201  1.1  christos     const uint8_t *msg, size_t msglen,
    202  1.1  christos     const uint8_t *ctx, size_t ctxlen,
    203  1.1  christos     const uint8_t pk[MLDSA44_PUBLICKEYBYTES])
    204  1.1  christos {
    205  1.1  christos 	libcrux_mldsa44_pk pk_internal;
    206  1.1  christos 	libcrux_mldsa44_signature sig_internal;
    207  1.1  christos 	libcrux_mldsa44_message message = { msg, msglen };
    208  1.1  christos 	libcrux_mldsa44_message context = { ctx, ctxlen };
    209  1.1  christos 	libcrux_mldsa44_verify_result res;
    210  1.1  christos 
    211  1.1  christos 	memcpy(pk_internal.data, pk, MLDSA44_PUBLICKEYBYTES);
    212  1.1  christos 	memcpy(sig_internal.data, sig, MLDSA44_SIGBYTES);
    213  1.1  christos 	res = libcrux_ml_dsa_ml_dsa_44_portable_verify(&pk_internal,
    214  1.1  christos 	    message, context, &sig_internal);
    215  1.1  christos 
    216  1.1  christos 	return (res.tag == LIBCRUX_RESULT_OK) ? 0 : -1;
    217  1.1  christos }
    218  1.1  christos 
    219  1.1  christos /* ML-DSA 65 */
    220  1.1  christos 
    221  1.1  christos #if 0
    222  1.1  christos int
    223  1.1  christos crypto_sign_mldsa65_keypair(uint8_t pk[MLDSA65_PUBLICKEYBYTES],
    224  1.1  christos     uint8_t sk[MLDSA65_SECRETKEYBYTES])
    225  1.1  christos {
    226  1.1  christos 	uint8_t rnd[MLDSA65_SEEDBYTES];
    227  1.1  christos 	int r;
    228  1.1  christos 
    229  1.1  christos 	arc4random_buf(rnd, sizeof(rnd));
    230  1.1  christos 	r = crypto_sign_mldsa65_keypair_seeded(pk, sk, rnd);
    231  1.1  christos 	explicit_bzero(rnd, sizeof(rnd));
    232  1.1  christos 	return r;
    233  1.1  christos }
    234  1.1  christos 
    235  1.1  christos int
    236  1.1  christos crypto_sign_mldsa65_keypair_seeded(uint8_t pk[MLDSA65_PUBLICKEYBYTES],
    237  1.1  christos     uint8_t sk[MLDSA65_SECRETKEYBYTES], const uint8_t seed[MLDSA65_SEEDBYTES])
    238  1.1  christos {
    239  1.1  christos 	libcrux_mldsa65_keypair_rnd rnd;
    240  1.1  christos 	libcrux_mldsa65_keypair keypair;
    241  1.1  christos 
    242  1.1  christos 	memcpy(rnd.data, seed, sizeof(rnd.data));
    243  1.1  christos 	keypair = libcrux_ml_dsa_ml_dsa_65_portable_generate_key_pair(rnd);
    244  1.1  christos 	memcpy(pk, keypair.verification_key.data, MLDSA65_PUBLICKEYBYTES);
    245  1.1  christos 	memcpy(sk, keypair.signing_key.data, MLDSA65_SECRETKEYBYTES);
    246  1.1  christos 
    247  1.1  christos 	explicit_bzero(&keypair, sizeof(keypair));
    248  1.1  christos 	explicit_bzero(&rnd, sizeof(rnd));
    249  1.1  christos 	return 0;
    250  1.1  christos }
    251  1.1  christos 
    252  1.1  christos int
    253  1.1  christos crypto_sign_mldsa65(uint8_t sig[MLDSA65_SIGBYTES],
    254  1.1  christos     const uint8_t *msg, size_t msglen,
    255  1.1  christos     const uint8_t *ctx, size_t ctxlen,
    256  1.1  christos     const uint8_t sk[MLDSA65_SECRETKEYBYTES])
    257  1.1  christos {
    258  1.1  christos 	uint8_t rnd[MLDSA65_SEEDBYTES];
    259  1.1  christos 	int r;
    260  1.1  christos 
    261  1.1  christos 	arc4random_buf(rnd, sizeof(rnd));
    262  1.1  christos 	r = crypto_sign_mldsa65_seeded(sig, msg, msglen, ctx, ctxlen, sk, rnd);
    263  1.1  christos 	explicit_bzero(rnd, sizeof(rnd));
    264  1.1  christos 	return r;
    265  1.1  christos }
    266  1.1  christos 
    267  1.1  christos int
    268  1.1  christos crypto_sign_mldsa65_seeded(uint8_t sig[MLDSA65_SIGBYTES],
    269  1.1  christos     const uint8_t *msg, size_t msglen,
    270  1.1  christos     const uint8_t *ctx, size_t ctxlen,
    271  1.1  christos     const uint8_t sk[MLDSA65_SECRETKEYBYTES],
    272  1.1  christos     const uint8_t seed[MLDSA65_SEEDBYTES])
    273  1.1  christos {
    274  1.1  christos 	libcrux_mldsa65_sign_rnd rnd;
    275  1.1  christos 	libcrux_mldsa65_sk sk_internal;
    276  1.1  christos 	libcrux_mldsa65_message message = { msg, msglen };
    277  1.1  christos 	libcrux_mldsa65_message context = { ctx, ctxlen };
    278  1.1  christos 	libcrux_mldsa65_sign_result res;
    279  1.1  christos 	int r = -1;
    280  1.1  christos 
    281  1.1  christos 	memcpy(sk_internal.data, sk, MLDSA65_SECRETKEYBYTES);
    282  1.1  christos 	memcpy(rnd.data, seed, sizeof(rnd.data));
    283  1.1  christos 	res = libcrux_ml_dsa_ml_dsa_65_portable_sign(&sk_internal,
    284  1.1  christos 	    message, context, rnd);
    285  1.1  christos 	if (res.tag == LIBCRUX_RESULT_OK) {
    286  1.1  christos 		memcpy(sig, res.val.case_Ok.data, MLDSA65_SIGBYTES);
    287  1.1  christos 		r = 0;
    288  1.1  christos 	}
    289  1.1  christos 
    290  1.1  christos 	explicit_bzero(&sk_internal, sizeof(sk_internal));
    291  1.1  christos 	explicit_bzero(&res, sizeof(res));
    292  1.1  christos 	explicit_bzero(&rnd, sizeof(rnd));
    293  1.1  christos 	return r;
    294  1.1  christos }
    295  1.1  christos 
    296  1.1  christos int
    297  1.1  christos crypto_sign_mldsa65_verify(const uint8_t sig[MLDSA65_SIGBYTES],
    298  1.1  christos     const uint8_t *msg, size_t msglen,
    299  1.1  christos     const uint8_t *ctx, size_t ctxlen,
    300  1.1  christos     const uint8_t pk[MLDSA65_PUBLICKEYBYTES])
    301  1.1  christos {
    302  1.1  christos 	libcrux_mldsa65_pk pk_internal;
    303  1.1  christos 	libcrux_mldsa65_signature sig_internal;
    304  1.1  christos 	libcrux_mldsa65_message message = { msg, msglen };
    305  1.1  christos 	libcrux_mldsa65_message context = { ctx, ctxlen };
    306  1.1  christos 	libcrux_mldsa65_verify_result res;
    307  1.1  christos 
    308  1.1  christos 	memcpy(pk_internal.data, pk, MLDSA65_PUBLICKEYBYTES);
    309  1.1  christos 	memcpy(sig_internal.data, sig, MLDSA65_SIGBYTES);
    310  1.1  christos 	res = libcrux_ml_dsa_ml_dsa_65_portable_verify(&pk_internal,
    311  1.1  christos 	    message, context, &sig_internal);
    312  1.1  christos 
    313  1.1  christos 	return (res.tag == LIBCRUX_RESULT_OK) ? 0 : -1;
    314  1.1  christos }
    315  1.1  christos #endif
    316  1.1  christos 
    317  1.1  christos /* ML-DSA 87 */
    318  1.1  christos 
    319  1.1  christos #if 0
    320  1.1  christos int
    321  1.1  christos crypto_sign_mldsa87_keypair(uint8_t pk[MLDSA87_PUBLICKEYBYTES],
    322  1.1  christos     uint8_t sk[MLDSA87_SECRETKEYBYTES])
    323  1.1  christos {
    324  1.1  christos 	uint8_t rnd[MLDSA87_SEEDBYTES];
    325  1.1  christos 	int r;
    326  1.1  christos 
    327  1.1  christos 	arc4random_buf(rnd, sizeof(rnd));
    328  1.1  christos 	r = crypto_sign_mldsa87_keypair_seeded(pk, sk, rnd);
    329  1.1  christos 	explicit_bzero(rnd, sizeof(rnd));
    330  1.1  christos 	return r;
    331  1.1  christos }
    332  1.1  christos 
    333  1.1  christos int
    334  1.1  christos crypto_sign_mldsa87_keypair_seeded(uint8_t pk[MLDSA87_PUBLICKEYBYTES],
    335  1.1  christos     uint8_t sk[MLDSA87_SECRETKEYBYTES], const uint8_t seed[MLDSA87_SEEDBYTES])
    336  1.1  christos {
    337  1.1  christos 	libcrux_mldsa87_keypair_rnd rnd;
    338  1.1  christos 	libcrux_mldsa87_keypair keypair;
    339  1.1  christos 
    340  1.1  christos 	memcpy(rnd.data, seed, sizeof(rnd.data));
    341  1.1  christos 	keypair = libcrux_ml_dsa_ml_dsa_87_portable_generate_key_pair(rnd);
    342  1.1  christos 	memcpy(pk, keypair.verification_key.data, MLDSA87_PUBLICKEYBYTES);
    343  1.1  christos 	memcpy(sk, keypair.signing_key.data, MLDSA87_SECRETKEYBYTES);
    344  1.1  christos 
    345  1.1  christos 	explicit_bzero(&keypair, sizeof(keypair));
    346  1.1  christos 	explicit_bzero(&rnd, sizeof(rnd));
    347  1.1  christos 	return 0;
    348  1.1  christos }
    349  1.1  christos 
    350  1.1  christos int
    351  1.1  christos crypto_sign_mldsa87(uint8_t sig[MLDSA87_SIGBYTES],
    352  1.1  christos     const uint8_t *msg, size_t msglen,
    353  1.1  christos     const uint8_t *ctx, size_t ctxlen,
    354  1.1  christos     const uint8_t sk[MLDSA87_SECRETKEYBYTES])
    355  1.1  christos {
    356  1.1  christos 	uint8_t rnd[MLDSA87_SEEDBYTES];
    357  1.1  christos 	int r;
    358  1.1  christos 
    359  1.1  christos 	arc4random_buf(rnd, sizeof(rnd));
    360  1.1  christos 	r = crypto_sign_mldsa87_seeded(sig, msg, msglen, ctx, ctxlen, sk, rnd);
    361  1.1  christos 	explicit_bzero(rnd, sizeof(rnd));
    362  1.1  christos 	return r;
    363  1.1  christos }
    364  1.1  christos 
    365  1.1  christos int
    366  1.1  christos crypto_sign_mldsa87_seeded(uint8_t sig[MLDSA87_SIGBYTES],
    367  1.1  christos     const uint8_t *msg, size_t msglen,
    368  1.1  christos     const uint8_t *ctx, size_t ctxlen,
    369  1.1  christos     const uint8_t sk[MLDSA87_SECRETKEYBYTES],
    370  1.1  christos     const uint8_t seed[MLDSA87_SEEDBYTES])
    371  1.1  christos {
    372  1.1  christos 	libcrux_mldsa87_sign_rnd rnd;
    373  1.1  christos 	libcrux_mldsa87_sk sk_internal;
    374  1.1  christos 	libcrux_mldsa87_message message = { msg, msglen };
    375  1.1  christos 	libcrux_mldsa87_message context = { ctx, ctxlen };
    376  1.1  christos 	libcrux_mldsa87_sign_result res;
    377  1.1  christos 	int r = -1;
    378  1.1  christos 
    379  1.1  christos 	memcpy(sk_internal.data, sk, MLDSA87_SECRETKEYBYTES);
    380  1.1  christos 	memcpy(rnd.data, seed, sizeof(rnd.data));
    381  1.1  christos 	res = libcrux_ml_dsa_ml_dsa_87_portable_sign(&sk_internal,
    382  1.1  christos 	    message, context, rnd);
    383  1.1  christos 	if (res.tag == LIBCRUX_RESULT_OK) {
    384  1.1  christos 		memcpy(sig, res.val.case_Ok.data, MLDSA87_SIGBYTES);
    385  1.1  christos 		r = 0;
    386  1.1  christos 	}
    387  1.1  christos 
    388  1.1  christos 	explicit_bzero(&sk_internal, sizeof(sk_internal));
    389  1.1  christos 	explicit_bzero(&res, sizeof(res));
    390  1.1  christos 	explicit_bzero(&rnd, sizeof(rnd));
    391  1.1  christos 	return r;
    392  1.1  christos }
    393  1.1  christos 
    394  1.1  christos int
    395  1.1  christos crypto_sign_mldsa87_verify(const uint8_t sig[MLDSA87_SIGBYTES],
    396  1.1  christos     const uint8_t *msg, size_t msglen,
    397  1.1  christos     const uint8_t *ctx, size_t ctxlen,
    398  1.1  christos     const uint8_t pk[MLDSA87_PUBLICKEYBYTES])
    399  1.1  christos {
    400  1.1  christos 	libcrux_mldsa87_pk pk_internal;
    401  1.1  christos 	libcrux_mldsa87_signature sig_internal;
    402  1.1  christos 	libcrux_mldsa87_message message = { msg, msglen };
    403  1.1  christos 	libcrux_mldsa87_message context = { ctx, ctxlen };
    404  1.1  christos 	libcrux_mldsa87_verify_result res;
    405  1.1  christos 
    406  1.1  christos 	memcpy(pk_internal.data, pk, MLDSA87_PUBLICKEYBYTES);
    407  1.1  christos 	memcpy(sig_internal.data, sig, MLDSA87_SIGBYTES);
    408  1.1  christos 	res = libcrux_ml_dsa_ml_dsa_87_portable_verify(&pk_internal,
    409  1.1  christos 	    message, context, &sig_internal);
    410  1.1  christos 
    411  1.1  christos 	return (res.tag == LIBCRUX_RESULT_OK) ? 0 : -1;
    412  1.1  christos }
    413  1.1  christos #endif
    414  1.1  christos 
    415  1.1  christos void
    416  1.1  christos sha3_256(uint8_t digest[32], const uint8_t *data, size_t len)
    417  1.1  christos {
    418  1.1  christos 	Eurydice_borrow_slice_u8 input = { data, len };
    419  1.1  christos 	Eurydice_mut_borrow_slice_u8 output = { digest, 32 };
    420  1.1  christos 	libcrux_sha3_portable_sha256(output, input);
    421  1.1  christos }
    422  1.1  christos 
    423  1.1  christos void
    424  1.1  christos sha3_512(uint8_t digest[64], const uint8_t *data, size_t len)
    425  1.1  christos {
    426  1.1  christos 	Eurydice_borrow_slice_u8 input = { data, len };
    427  1.1  christos 	Eurydice_mut_borrow_slice_u8 output = { digest, 64 };
    428  1.1  christos 	libcrux_sha3_portable_sha512(output, input);
    429  1.1  christos }
    430