pq_crypto 0.1.0
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.
- checksums.yaml +7 -0
- data/.github/workflows/ci.yml +37 -0
- data/CHANGELOG.md +29 -0
- data/GET_STARTED.md +65 -0
- data/LICENSE.txt +21 -0
- data/README.md +135 -0
- data/SECURITY.md +57 -0
- data/ext/pqcrypto/extconf.rb +157 -0
- data/ext/pqcrypto/mldsa_api.h +51 -0
- data/ext/pqcrypto/mlkem_api.h +21 -0
- data/ext/pqcrypto/pqcrypto_ruby_secure.c +889 -0
- data/ext/pqcrypto/pqcrypto_secure.c +1178 -0
- data/ext/pqcrypto/pqcrypto_secure.h +135 -0
- data/ext/pqcrypto/vendor/.vendored +5 -0
- data/ext/pqcrypto/vendor/pqclean/common/aes.c +639 -0
- data/ext/pqcrypto/vendor/pqclean/common/aes.h +64 -0
- data/ext/pqcrypto/vendor/pqclean/common/compat.h +73 -0
- data/ext/pqcrypto/vendor/pqclean/common/crypto_declassify.h +7 -0
- data/ext/pqcrypto/vendor/pqclean/common/fips202.c +928 -0
- data/ext/pqcrypto/vendor/pqclean/common/fips202.h +166 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak2x/feat.S +168 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak2x/fips202x2.c +684 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak2x/fips202x2.h +60 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak4x/KeccakP-1600-times4-SIMD256.c +1028 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak4x/KeccakP-1600-times4-SnP.h +50 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak4x/KeccakP-1600-unrolling.macros +198 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak4x/Makefile +8 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak4x/Makefile.Microsoft_nmake +8 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak4x/SIMD256-config.h +3 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak4x/align.h +34 -0
- data/ext/pqcrypto/vendor/pqclean/common/keccak4x/brg_endian.h +142 -0
- data/ext/pqcrypto/vendor/pqclean/common/nistseedexpander.c +101 -0
- data/ext/pqcrypto/vendor/pqclean/common/nistseedexpander.h +39 -0
- data/ext/pqcrypto/vendor/pqclean/common/randombytes.c +355 -0
- data/ext/pqcrypto/vendor/pqclean/common/randombytes.h +27 -0
- data/ext/pqcrypto/vendor/pqclean/common/sha2.c +769 -0
- data/ext/pqcrypto/vendor/pqclean/common/sha2.h +173 -0
- data/ext/pqcrypto/vendor/pqclean/common/sp800-185.c +156 -0
- data/ext/pqcrypto/vendor/pqclean/common/sp800-185.h +27 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/LICENSE +5 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/Makefile +19 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/Makefile.Microsoft_nmake +23 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/api.h +18 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/cbd.c +83 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/cbd.h +11 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/indcpa.c +327 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/indcpa.h +22 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/kem.c +164 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/kem.h +23 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/ntt.c +146 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/ntt.h +14 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/params.h +36 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/poly.c +299 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/poly.h +37 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/polyvec.c +188 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/polyvec.h +26 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/reduce.c +41 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/reduce.h +13 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/symmetric-shake.c +71 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/symmetric.h +30 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/verify.c +67 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_kem/ml-kem-768/clean/verify.h +13 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/LICENSE +5 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/Makefile +19 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/Makefile.Microsoft_nmake +23 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/api.h +50 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/ntt.c +98 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/ntt.h +10 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/packing.c +261 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/packing.h +31 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/params.h +44 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/poly.c +799 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/poly.h +52 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/polyvec.c +415 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/polyvec.h +65 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/reduce.c +69 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/reduce.h +17 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/rounding.c +92 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/rounding.h +14 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/sign.c +407 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/sign.h +47 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/symmetric-shake.c +26 -0
- data/ext/pqcrypto/vendor/pqclean/crypto_sign/ml-dsa-65/clean/symmetric.h +34 -0
- data/lib/pq_crypto/errors.rb +10 -0
- data/lib/pq_crypto/hybrid_kem.rb +106 -0
- data/lib/pq_crypto/kem.rb +199 -0
- data/lib/pq_crypto/serialization.rb +102 -0
- data/lib/pq_crypto/signature.rb +198 -0
- data/lib/pq_crypto/version.rb +5 -0
- data/lib/pq_crypto.rb +177 -0
- data/lib/pqcrypto.rb +3 -0
- data/script/vendor_libs.rb +199 -0
- metadata +195 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#include "fips202.h"
|
|
2
|
+
#include "params.h"
|
|
3
|
+
#include "symmetric.h"
|
|
4
|
+
#include <stddef.h>
|
|
5
|
+
#include <stdint.h>
|
|
6
|
+
#include <string.h>
|
|
7
|
+
|
|
8
|
+
/*************************************************
|
|
9
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_kyber_shake128_absorb
|
|
10
|
+
*
|
|
11
|
+
* Description: Absorb step of the SHAKE128 specialized for the Kyber context.
|
|
12
|
+
*
|
|
13
|
+
* Arguments: - xof_state *state: pointer to (uninitialized) output Keccak state
|
|
14
|
+
* - const uint8_t *seed: pointer to KYBER_SYMBYTES input to be absorbed into state
|
|
15
|
+
* - uint8_t i: additional byte of input
|
|
16
|
+
* - uint8_t j: additional byte of input
|
|
17
|
+
**************************************************/
|
|
18
|
+
void PQCLEAN_MLKEM768_CLEAN_kyber_shake128_absorb(xof_state *state,
|
|
19
|
+
const uint8_t seed[KYBER_SYMBYTES],
|
|
20
|
+
uint8_t x,
|
|
21
|
+
uint8_t y) {
|
|
22
|
+
uint8_t extseed[KYBER_SYMBYTES + 2];
|
|
23
|
+
|
|
24
|
+
memcpy(extseed, seed, KYBER_SYMBYTES);
|
|
25
|
+
extseed[KYBER_SYMBYTES + 0] = x;
|
|
26
|
+
extseed[KYBER_SYMBYTES + 1] = y;
|
|
27
|
+
|
|
28
|
+
shake128_absorb(state, extseed, sizeof(extseed));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/*************************************************
|
|
32
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_kyber_shake256_prf
|
|
33
|
+
*
|
|
34
|
+
* Description: Usage of SHAKE256 as a PRF, concatenates secret and public input
|
|
35
|
+
* and then generates outlen bytes of SHAKE256 output
|
|
36
|
+
*
|
|
37
|
+
* Arguments: - uint8_t *out: pointer to output
|
|
38
|
+
* - size_t outlen: number of requested output bytes
|
|
39
|
+
* - const uint8_t *key: pointer to the key (of length KYBER_SYMBYTES)
|
|
40
|
+
* - uint8_t nonce: single-byte nonce (public PRF input)
|
|
41
|
+
**************************************************/
|
|
42
|
+
void PQCLEAN_MLKEM768_CLEAN_kyber_shake256_prf(uint8_t *out, size_t outlen, const uint8_t key[KYBER_SYMBYTES], uint8_t nonce) {
|
|
43
|
+
uint8_t extkey[KYBER_SYMBYTES + 1];
|
|
44
|
+
|
|
45
|
+
memcpy(extkey, key, KYBER_SYMBYTES);
|
|
46
|
+
extkey[KYBER_SYMBYTES] = nonce;
|
|
47
|
+
|
|
48
|
+
shake256(out, outlen, extkey, sizeof(extkey));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/*************************************************
|
|
52
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_kyber_shake256_prf
|
|
53
|
+
*
|
|
54
|
+
* Description: Usage of SHAKE256 as a PRF, concatenates secret and public input
|
|
55
|
+
* and then generates outlen bytes of SHAKE256 output
|
|
56
|
+
*
|
|
57
|
+
* Arguments: - uint8_t *out: pointer to output
|
|
58
|
+
* - size_t outlen: number of requested output bytes
|
|
59
|
+
* - const uint8_t *key: pointer to the key (of length KYBER_SYMBYTES)
|
|
60
|
+
* - uint8_t nonce: single-byte nonce (public PRF input)
|
|
61
|
+
**************************************************/
|
|
62
|
+
void PQCLEAN_MLKEM768_CLEAN_kyber_shake256_rkprf(uint8_t out[KYBER_SSBYTES], const uint8_t key[KYBER_SYMBYTES], const uint8_t input[KYBER_CIPHERTEXTBYTES]) {
|
|
63
|
+
shake256incctx s;
|
|
64
|
+
|
|
65
|
+
shake256_inc_init(&s);
|
|
66
|
+
shake256_inc_absorb(&s, key, KYBER_SYMBYTES);
|
|
67
|
+
shake256_inc_absorb(&s, input, KYBER_CIPHERTEXTBYTES);
|
|
68
|
+
shake256_inc_finalize(&s);
|
|
69
|
+
shake256_inc_squeeze(out, KYBER_SSBYTES, &s);
|
|
70
|
+
shake256_inc_ctx_release(&s);
|
|
71
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#ifndef PQCLEAN_MLKEM768_CLEAN_SYMMETRIC_H
|
|
2
|
+
#define PQCLEAN_MLKEM768_CLEAN_SYMMETRIC_H
|
|
3
|
+
#include "fips202.h"
|
|
4
|
+
#include "params.h"
|
|
5
|
+
#include <stddef.h>
|
|
6
|
+
#include <stdint.h>
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
typedef shake128ctx xof_state;
|
|
10
|
+
|
|
11
|
+
void PQCLEAN_MLKEM768_CLEAN_kyber_shake128_absorb(xof_state *s,
|
|
12
|
+
const uint8_t seed[KYBER_SYMBYTES],
|
|
13
|
+
uint8_t x,
|
|
14
|
+
uint8_t y);
|
|
15
|
+
|
|
16
|
+
void PQCLEAN_MLKEM768_CLEAN_kyber_shake256_prf(uint8_t *out, size_t outlen, const uint8_t key[KYBER_SYMBYTES], uint8_t nonce);
|
|
17
|
+
|
|
18
|
+
void PQCLEAN_MLKEM768_CLEAN_kyber_shake256_rkprf(uint8_t out[KYBER_SSBYTES], const uint8_t key[KYBER_SYMBYTES], const uint8_t input[KYBER_CIPHERTEXTBYTES]);
|
|
19
|
+
|
|
20
|
+
#define XOF_BLOCKBYTES SHAKE128_RATE
|
|
21
|
+
|
|
22
|
+
#define hash_h(OUT, IN, INBYTES) sha3_256(OUT, IN, INBYTES)
|
|
23
|
+
#define hash_g(OUT, IN, INBYTES) sha3_512(OUT, IN, INBYTES)
|
|
24
|
+
#define xof_absorb(STATE, SEED, X, Y) PQCLEAN_MLKEM768_CLEAN_kyber_shake128_absorb(STATE, SEED, X, Y)
|
|
25
|
+
#define xof_squeezeblocks(OUT, OUTBLOCKS, STATE) shake128_squeezeblocks(OUT, OUTBLOCKS, STATE)
|
|
26
|
+
#define xof_ctx_release(STATE) shake128_ctx_release(STATE)
|
|
27
|
+
#define prf(OUT, OUTBYTES, KEY, NONCE) PQCLEAN_MLKEM768_CLEAN_kyber_shake256_prf(OUT, OUTBYTES, KEY, NONCE)
|
|
28
|
+
#define rkprf(OUT, KEY, INPUT) PQCLEAN_MLKEM768_CLEAN_kyber_shake256_rkprf(OUT, KEY, INPUT)
|
|
29
|
+
|
|
30
|
+
#endif /* SYMMETRIC_H */
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#include "compat.h"
|
|
2
|
+
#include "verify.h"
|
|
3
|
+
#include <stddef.h>
|
|
4
|
+
#include <stdint.h>
|
|
5
|
+
|
|
6
|
+
/*************************************************
|
|
7
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_verify
|
|
8
|
+
*
|
|
9
|
+
* Description: Compare two arrays for equality in constant time.
|
|
10
|
+
*
|
|
11
|
+
* Arguments: const uint8_t *a: pointer to first byte array
|
|
12
|
+
* const uint8_t *b: pointer to second byte array
|
|
13
|
+
* size_t len: length of the byte arrays
|
|
14
|
+
*
|
|
15
|
+
* Returns 0 if the byte arrays are equal, 1 otherwise
|
|
16
|
+
**************************************************/
|
|
17
|
+
int PQCLEAN_MLKEM768_CLEAN_verify(const uint8_t *a, const uint8_t *b, size_t len) {
|
|
18
|
+
size_t i;
|
|
19
|
+
uint8_t r = 0;
|
|
20
|
+
|
|
21
|
+
for (i = 0; i < len; i++) {
|
|
22
|
+
r |= a[i] ^ b[i];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return (-(uint64_t)r) >> 63;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/*************************************************
|
|
29
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_cmov
|
|
30
|
+
*
|
|
31
|
+
* Description: Copy len bytes from x to r if b is 1;
|
|
32
|
+
* don't modify x if b is 0. Requires b to be in {0,1};
|
|
33
|
+
* assumes two's complement representation of negative integers.
|
|
34
|
+
* Runs in constant time.
|
|
35
|
+
*
|
|
36
|
+
* Arguments: uint8_t *r: pointer to output byte array
|
|
37
|
+
* const uint8_t *x: pointer to input byte array
|
|
38
|
+
* size_t len: Amount of bytes to be copied
|
|
39
|
+
* uint8_t b: Condition bit; has to be in {0,1}
|
|
40
|
+
**************************************************/
|
|
41
|
+
void PQCLEAN_MLKEM768_CLEAN_cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b) {
|
|
42
|
+
size_t i;
|
|
43
|
+
|
|
44
|
+
PQCLEAN_PREVENT_BRANCH_HACK(b);
|
|
45
|
+
|
|
46
|
+
b = -b;
|
|
47
|
+
for (i = 0; i < len; i++) {
|
|
48
|
+
r[i] ^= b & (r[i] ^ x[i]);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
/*************************************************
|
|
54
|
+
* Name: PQCLEAN_MLKEM768_CLEAN_cmov_int16
|
|
55
|
+
*
|
|
56
|
+
* Description: Copy input v to *r if b is 1, don't modify *r if b is 0.
|
|
57
|
+
* Requires b to be in {0,1};
|
|
58
|
+
* Runs in constant time.
|
|
59
|
+
*
|
|
60
|
+
* Arguments: int16_t *r: pointer to output int16_t
|
|
61
|
+
* int16_t v: input int16_t
|
|
62
|
+
* uint8_t b: Condition bit; has to be in {0,1}
|
|
63
|
+
**************************************************/
|
|
64
|
+
void PQCLEAN_MLKEM768_CLEAN_cmov_int16(int16_t *r, int16_t v, uint16_t b) {
|
|
65
|
+
b = -b;
|
|
66
|
+
*r ^= b & ((*r) ^ v);
|
|
67
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#ifndef PQCLEAN_MLKEM768_CLEAN_VERIFY_H
|
|
2
|
+
#define PQCLEAN_MLKEM768_CLEAN_VERIFY_H
|
|
3
|
+
#include "params.h"
|
|
4
|
+
#include <stddef.h>
|
|
5
|
+
#include <stdint.h>
|
|
6
|
+
|
|
7
|
+
int PQCLEAN_MLKEM768_CLEAN_verify(const uint8_t *a, const uint8_t *b, size_t len);
|
|
8
|
+
|
|
9
|
+
void PQCLEAN_MLKEM768_CLEAN_cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b);
|
|
10
|
+
|
|
11
|
+
void PQCLEAN_MLKEM768_CLEAN_cmov_int16(int16_t *r, int16_t v, uint16_t b);
|
|
12
|
+
|
|
13
|
+
#endif
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# This Makefile can be used with GNU Make or BSD Make
|
|
2
|
+
|
|
3
|
+
LIB=libml-dsa-65_clean.a
|
|
4
|
+
HEADERS=api.h ntt.h packing.h params.h poly.h polyvec.h reduce.h rounding.h sign.h symmetric.h
|
|
5
|
+
OBJECTS=ntt.o packing.o poly.o polyvec.o reduce.o rounding.o sign.o symmetric-shake.o
|
|
6
|
+
|
|
7
|
+
CFLAGS=-O3 -Wall -Wextra -Wpedantic -Werror -Wmissing-prototypes -Wredundant-decls -std=c99 -I../../../common $(EXTRAFLAGS)
|
|
8
|
+
|
|
9
|
+
all: $(LIB)
|
|
10
|
+
|
|
11
|
+
%.o: %.c $(HEADERS)
|
|
12
|
+
$(CC) $(CFLAGS) -c -o $@ $<
|
|
13
|
+
|
|
14
|
+
$(LIB): $(OBJECTS)
|
|
15
|
+
$(AR) -r $@ $(OBJECTS)
|
|
16
|
+
|
|
17
|
+
clean:
|
|
18
|
+
$(RM) $(OBJECTS)
|
|
19
|
+
$(RM) $(LIB)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# This Makefile can be used with Microsoft Visual Studio's nmake using the command:
|
|
2
|
+
# nmake /f Makefile.Microsoft_nmake
|
|
3
|
+
|
|
4
|
+
LIBRARY=libml-dsa-65_clean.lib
|
|
5
|
+
OBJECTS=ntt.obj packing.obj poly.obj polyvec.obj reduce.obj rounding.obj sign.obj symmetric-shake.obj
|
|
6
|
+
|
|
7
|
+
# Warning C4146 is raised when a unary minus operator is applied to an
|
|
8
|
+
# unsigned type; this has nonetheless been standard and portable for as
|
|
9
|
+
# long as there has been a C standard, and we need it for constant-time
|
|
10
|
+
# computations. Thus, we disable that spurious warning.
|
|
11
|
+
CFLAGS=/nologo /O2 /I ..\..\..\common /W4 /WX /wd4146
|
|
12
|
+
|
|
13
|
+
all: $(LIBRARY)
|
|
14
|
+
|
|
15
|
+
# Make sure objects are recompiled if headers change.
|
|
16
|
+
$(OBJECTS): *.h
|
|
17
|
+
|
|
18
|
+
$(LIBRARY): $(OBJECTS)
|
|
19
|
+
LIB.EXE /NOLOGO /WX /OUT:$@ $**
|
|
20
|
+
|
|
21
|
+
clean:
|
|
22
|
+
-DEL $(OBJECTS)
|
|
23
|
+
-DEL $(LIBRARY)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#ifndef PQCLEAN_MLDSA65_CLEAN_API_H
|
|
2
|
+
#define PQCLEAN_MLDSA65_CLEAN_API_H
|
|
3
|
+
|
|
4
|
+
#include <stddef.h>
|
|
5
|
+
#include <stdint.h>
|
|
6
|
+
|
|
7
|
+
#define PQCLEAN_MLDSA65_CLEAN_CRYPTO_PUBLICKEYBYTES 1952
|
|
8
|
+
#define PQCLEAN_MLDSA65_CLEAN_CRYPTO_SECRETKEYBYTES 4032
|
|
9
|
+
#define PQCLEAN_MLDSA65_CLEAN_CRYPTO_BYTES 3309
|
|
10
|
+
#define PQCLEAN_MLDSA65_CLEAN_CRYPTO_ALGNAME "ML-DSA-65"
|
|
11
|
+
|
|
12
|
+
int PQCLEAN_MLDSA65_CLEAN_crypto_sign_keypair(uint8_t *pk, uint8_t *sk);
|
|
13
|
+
|
|
14
|
+
int PQCLEAN_MLDSA65_CLEAN_crypto_sign_signature_ctx(uint8_t *sig, size_t *siglen,
|
|
15
|
+
const uint8_t *m, size_t mlen,
|
|
16
|
+
const uint8_t *ctx, size_t ctxlen,
|
|
17
|
+
const uint8_t *sk);
|
|
18
|
+
|
|
19
|
+
int PQCLEAN_MLDSA65_CLEAN_crypto_sign_ctx(uint8_t *sm, size_t *smlen,
|
|
20
|
+
const uint8_t *m, size_t mlen,
|
|
21
|
+
const uint8_t *ctx, size_t ctxlen,
|
|
22
|
+
const uint8_t *sk);
|
|
23
|
+
|
|
24
|
+
int PQCLEAN_MLDSA65_CLEAN_crypto_sign_verify_ctx(const uint8_t *sig, size_t siglen,
|
|
25
|
+
const uint8_t *m, size_t mlen,
|
|
26
|
+
const uint8_t *ctx, size_t ctxlen,
|
|
27
|
+
const uint8_t *pk);
|
|
28
|
+
|
|
29
|
+
int PQCLEAN_MLDSA65_CLEAN_crypto_sign_open_ctx(uint8_t *m, size_t *mlen,
|
|
30
|
+
const uint8_t *sm, size_t smlen,
|
|
31
|
+
const uint8_t *ctx, size_t ctxlen,
|
|
32
|
+
const uint8_t *pk);
|
|
33
|
+
|
|
34
|
+
int PQCLEAN_MLDSA65_CLEAN_crypto_sign_signature(uint8_t *sig, size_t *siglen,
|
|
35
|
+
const uint8_t *m, size_t mlen,
|
|
36
|
+
const uint8_t *sk);
|
|
37
|
+
|
|
38
|
+
int PQCLEAN_MLDSA65_CLEAN_crypto_sign(uint8_t *sm, size_t *smlen,
|
|
39
|
+
const uint8_t *m, size_t mlen,
|
|
40
|
+
const uint8_t *sk);
|
|
41
|
+
|
|
42
|
+
int PQCLEAN_MLDSA65_CLEAN_crypto_sign_verify(const uint8_t *sig, size_t siglen,
|
|
43
|
+
const uint8_t *m, size_t mlen,
|
|
44
|
+
const uint8_t *pk);
|
|
45
|
+
|
|
46
|
+
int PQCLEAN_MLDSA65_CLEAN_crypto_sign_open(uint8_t *m, size_t *mlen,
|
|
47
|
+
const uint8_t *sm, size_t smlen,
|
|
48
|
+
const uint8_t *pk);
|
|
49
|
+
|
|
50
|
+
#endif
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#include "ntt.h"
|
|
2
|
+
#include "params.h"
|
|
3
|
+
#include "reduce.h"
|
|
4
|
+
#include <stdint.h>
|
|
5
|
+
|
|
6
|
+
static const int32_t zetas[N] = {
|
|
7
|
+
0, 25847, -2608894, -518909, 237124, -777960, -876248, 466468,
|
|
8
|
+
1826347, 2353451, -359251, -2091905, 3119733, -2884855, 3111497, 2680103,
|
|
9
|
+
2725464, 1024112, -1079900, 3585928, -549488, -1119584, 2619752, -2108549,
|
|
10
|
+
-2118186, -3859737, -1399561, -3277672, 1757237, -19422, 4010497, 280005,
|
|
11
|
+
2706023, 95776, 3077325, 3530437, -1661693, -3592148, -2537516, 3915439,
|
|
12
|
+
-3861115, -3043716, 3574422, -2867647, 3539968, -300467, 2348700, -539299,
|
|
13
|
+
-1699267, -1643818, 3505694, -3821735, 3507263, -2140649, -1600420, 3699596,
|
|
14
|
+
811944, 531354, 954230, 3881043, 3900724, -2556880, 2071892, -2797779,
|
|
15
|
+
-3930395, -1528703, -3677745, -3041255, -1452451, 3475950, 2176455, -1585221,
|
|
16
|
+
-1257611, 1939314, -4083598, -1000202, -3190144, -3157330, -3632928, 126922,
|
|
17
|
+
3412210, -983419, 2147896, 2715295, -2967645, -3693493, -411027, -2477047,
|
|
18
|
+
-671102, -1228525, -22981, -1308169, -381987, 1349076, 1852771, -1430430,
|
|
19
|
+
-3343383, 264944, 508951, 3097992, 44288, -1100098, 904516, 3958618,
|
|
20
|
+
-3724342, -8578, 1653064, -3249728, 2389356, -210977, 759969, -1316856,
|
|
21
|
+
189548, -3553272, 3159746, -1851402, -2409325, -177440, 1315589, 1341330,
|
|
22
|
+
1285669, -1584928, -812732, -1439742, -3019102, -3881060, -3628969, 3839961,
|
|
23
|
+
2091667, 3407706, 2316500, 3817976, -3342478, 2244091, -2446433, -3562462,
|
|
24
|
+
266997, 2434439, -1235728, 3513181, -3520352, -3759364, -1197226, -3193378,
|
|
25
|
+
900702, 1859098, 909542, 819034, 495491, -1613174, -43260, -522500,
|
|
26
|
+
-655327, -3122442, 2031748, 3207046, -3556995, -525098, -768622, -3595838,
|
|
27
|
+
342297, 286988, -2437823, 4108315, 3437287, -3342277, 1735879, 203044,
|
|
28
|
+
2842341, 2691481, -2590150, 1265009, 4055324, 1247620, 2486353, 1595974,
|
|
29
|
+
-3767016, 1250494, 2635921, -3548272, -2994039, 1869119, 1903435, -1050970,
|
|
30
|
+
-1333058, 1237275, -3318210, -1430225, -451100, 1312455, 3306115, -1962642,
|
|
31
|
+
-1279661, 1917081, -2546312, -1374803, 1500165, 777191, 2235880, 3406031,
|
|
32
|
+
-542412, -2831860, -1671176, -1846953, -2584293, -3724270, 594136, -3776993,
|
|
33
|
+
-2013608, 2432395, 2454455, -164721, 1957272, 3369112, 185531, -1207385,
|
|
34
|
+
-3183426, 162844, 1616392, 3014001, 810149, 1652634, -3694233, -1799107,
|
|
35
|
+
-3038916, 3523897, 3866901, 269760, 2213111, -975884, 1717735, 472078,
|
|
36
|
+
-426683, 1723600, -1803090, 1910376, -1667432, -1104333, -260646, -3833893,
|
|
37
|
+
-2939036, -2235985, -420899, -2286327, 183443, -976891, 1612842, -3545687,
|
|
38
|
+
-554416, 3919660, -48306, -1362209, 3937738, 1400424, -846154, 1976782
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/*************************************************
|
|
42
|
+
* Name: PQCLEAN_MLDSA65_CLEAN_ntt
|
|
43
|
+
*
|
|
44
|
+
* Description: Forward NTT, in-place. No modular reduction is performed after
|
|
45
|
+
* additions or subtractions. Output vector is in bitreversed order.
|
|
46
|
+
*
|
|
47
|
+
* Arguments: - uint32_t p[N]: input/output coefficient array
|
|
48
|
+
**************************************************/
|
|
49
|
+
void PQCLEAN_MLDSA65_CLEAN_ntt(int32_t a[N]) {
|
|
50
|
+
unsigned int len, start, j, k;
|
|
51
|
+
int32_t zeta, t;
|
|
52
|
+
|
|
53
|
+
k = 0;
|
|
54
|
+
for (len = 128; len > 0; len >>= 1) {
|
|
55
|
+
for (start = 0; start < N; start = j + len) {
|
|
56
|
+
zeta = zetas[++k];
|
|
57
|
+
for (j = start; j < start + len; ++j) {
|
|
58
|
+
t = PQCLEAN_MLDSA65_CLEAN_montgomery_reduce((int64_t)zeta * a[j + len]);
|
|
59
|
+
a[j + len] = a[j] - t;
|
|
60
|
+
a[j] = a[j] + t;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/*************************************************
|
|
67
|
+
* Name: PQCLEAN_MLDSA65_CLEAN_invntt_tomont
|
|
68
|
+
*
|
|
69
|
+
* Description: Inverse NTT and multiplication by Montgomery factor 2^32.
|
|
70
|
+
* In-place. No modular reductions after additions or
|
|
71
|
+
* subtractions; input coefficients need to be smaller than
|
|
72
|
+
* Q in absolute value. Output coefficient are smaller than Q in
|
|
73
|
+
* absolute value.
|
|
74
|
+
*
|
|
75
|
+
* Arguments: - uint32_t p[N]: input/output coefficient array
|
|
76
|
+
**************************************************/
|
|
77
|
+
void PQCLEAN_MLDSA65_CLEAN_invntt_tomont(int32_t a[N]) {
|
|
78
|
+
unsigned int start, len, j, k;
|
|
79
|
+
int32_t t, zeta;
|
|
80
|
+
const int32_t f = 41978; // mont^2/256
|
|
81
|
+
|
|
82
|
+
k = 256;
|
|
83
|
+
for (len = 1; len < N; len <<= 1) {
|
|
84
|
+
for (start = 0; start < N; start = j + len) {
|
|
85
|
+
zeta = -zetas[--k];
|
|
86
|
+
for (j = start; j < start + len; ++j) {
|
|
87
|
+
t = a[j];
|
|
88
|
+
a[j] = t + a[j + len];
|
|
89
|
+
a[j + len] = t - a[j + len];
|
|
90
|
+
a[j + len] = PQCLEAN_MLDSA65_CLEAN_montgomery_reduce((int64_t)zeta * a[j + len]);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
for (j = 0; j < N; ++j) {
|
|
96
|
+
a[j] = PQCLEAN_MLDSA65_CLEAN_montgomery_reduce((int64_t)f * a[j]);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
#include "packing.h"
|
|
2
|
+
#include "params.h"
|
|
3
|
+
#include "poly.h"
|
|
4
|
+
#include "polyvec.h"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/*************************************************
|
|
8
|
+
* Name: PQCLEAN_MLDSA65_CLEAN_pack_pk
|
|
9
|
+
*
|
|
10
|
+
* Description: Bit-pack public key pk = (rho, t1).
|
|
11
|
+
*
|
|
12
|
+
* Arguments: - uint8_t pk[]: output byte array
|
|
13
|
+
* - const uint8_t rho[]: byte array containing rho
|
|
14
|
+
* - const polyveck *t1: pointer to vector t1
|
|
15
|
+
**************************************************/
|
|
16
|
+
void PQCLEAN_MLDSA65_CLEAN_pack_pk(uint8_t pk[PQCLEAN_MLDSA65_CLEAN_CRYPTO_PUBLICKEYBYTES],
|
|
17
|
+
const uint8_t rho[SEEDBYTES],
|
|
18
|
+
const polyveck *t1) {
|
|
19
|
+
unsigned int i;
|
|
20
|
+
|
|
21
|
+
for (i = 0; i < SEEDBYTES; ++i) {
|
|
22
|
+
pk[i] = rho[i];
|
|
23
|
+
}
|
|
24
|
+
pk += SEEDBYTES;
|
|
25
|
+
|
|
26
|
+
for (i = 0; i < K; ++i) {
|
|
27
|
+
PQCLEAN_MLDSA65_CLEAN_polyt1_pack(pk + i * POLYT1_PACKEDBYTES, &t1->vec[i]);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/*************************************************
|
|
32
|
+
* Name: PQCLEAN_MLDSA65_CLEAN_unpack_pk
|
|
33
|
+
*
|
|
34
|
+
* Description: Unpack public key pk = (rho, t1).
|
|
35
|
+
*
|
|
36
|
+
* Arguments: - const uint8_t rho[]: output byte array for rho
|
|
37
|
+
* - const polyveck *t1: pointer to output vector t1
|
|
38
|
+
* - uint8_t pk[]: byte array containing bit-packed pk
|
|
39
|
+
**************************************************/
|
|
40
|
+
void PQCLEAN_MLDSA65_CLEAN_unpack_pk(uint8_t rho[SEEDBYTES],
|
|
41
|
+
polyveck *t1,
|
|
42
|
+
const uint8_t pk[PQCLEAN_MLDSA65_CLEAN_CRYPTO_PUBLICKEYBYTES]) {
|
|
43
|
+
unsigned int i;
|
|
44
|
+
|
|
45
|
+
for (i = 0; i < SEEDBYTES; ++i) {
|
|
46
|
+
rho[i] = pk[i];
|
|
47
|
+
}
|
|
48
|
+
pk += SEEDBYTES;
|
|
49
|
+
|
|
50
|
+
for (i = 0; i < K; ++i) {
|
|
51
|
+
PQCLEAN_MLDSA65_CLEAN_polyt1_unpack(&t1->vec[i], pk + i * POLYT1_PACKEDBYTES);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/*************************************************
|
|
56
|
+
* Name: PQCLEAN_MLDSA65_CLEAN_pack_sk
|
|
57
|
+
*
|
|
58
|
+
* Description: Bit-pack secret key sk = (rho, tr, key, t0, s1, s2).
|
|
59
|
+
*
|
|
60
|
+
* Arguments: - uint8_t sk[]: output byte array
|
|
61
|
+
* - const uint8_t rho[]: byte array containing rho
|
|
62
|
+
* - const uint8_t tr[]: byte array containing tr
|
|
63
|
+
* - const uint8_t key[]: byte array containing key
|
|
64
|
+
* - const polyveck *t0: pointer to vector t0
|
|
65
|
+
* - const polyvecl *s1: pointer to vector s1
|
|
66
|
+
* - const polyveck *s2: pointer to vector s2
|
|
67
|
+
**************************************************/
|
|
68
|
+
void PQCLEAN_MLDSA65_CLEAN_pack_sk(uint8_t sk[PQCLEAN_MLDSA65_CLEAN_CRYPTO_SECRETKEYBYTES],
|
|
69
|
+
const uint8_t rho[SEEDBYTES],
|
|
70
|
+
const uint8_t tr[TRBYTES],
|
|
71
|
+
const uint8_t key[SEEDBYTES],
|
|
72
|
+
const polyveck *t0,
|
|
73
|
+
const polyvecl *s1,
|
|
74
|
+
const polyveck *s2) {
|
|
75
|
+
unsigned int i;
|
|
76
|
+
|
|
77
|
+
for (i = 0; i < SEEDBYTES; ++i) {
|
|
78
|
+
sk[i] = rho[i];
|
|
79
|
+
}
|
|
80
|
+
sk += SEEDBYTES;
|
|
81
|
+
|
|
82
|
+
for (i = 0; i < SEEDBYTES; ++i) {
|
|
83
|
+
sk[i] = key[i];
|
|
84
|
+
}
|
|
85
|
+
sk += SEEDBYTES;
|
|
86
|
+
|
|
87
|
+
for (i = 0; i < TRBYTES; ++i) {
|
|
88
|
+
sk[i] = tr[i];
|
|
89
|
+
}
|
|
90
|
+
sk += TRBYTES;
|
|
91
|
+
|
|
92
|
+
for (i = 0; i < L; ++i) {
|
|
93
|
+
PQCLEAN_MLDSA65_CLEAN_polyeta_pack(sk + i * POLYETA_PACKEDBYTES, &s1->vec[i]);
|
|
94
|
+
}
|
|
95
|
+
sk += L * POLYETA_PACKEDBYTES;
|
|
96
|
+
|
|
97
|
+
for (i = 0; i < K; ++i) {
|
|
98
|
+
PQCLEAN_MLDSA65_CLEAN_polyeta_pack(sk + i * POLYETA_PACKEDBYTES, &s2->vec[i]);
|
|
99
|
+
}
|
|
100
|
+
sk += K * POLYETA_PACKEDBYTES;
|
|
101
|
+
|
|
102
|
+
for (i = 0; i < K; ++i) {
|
|
103
|
+
PQCLEAN_MLDSA65_CLEAN_polyt0_pack(sk + i * POLYT0_PACKEDBYTES, &t0->vec[i]);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/*************************************************
|
|
108
|
+
* Name: PQCLEAN_MLDSA65_CLEAN_unpack_sk
|
|
109
|
+
*
|
|
110
|
+
* Description: Unpack secret key sk = (rho, tr, key, t0, s1, s2).
|
|
111
|
+
*
|
|
112
|
+
* Arguments: - const uint8_t rho[]: output byte array for rho
|
|
113
|
+
* - const uint8_t tr[]: output byte array for tr
|
|
114
|
+
* - const uint8_t key[]: output byte array for key
|
|
115
|
+
* - const polyveck *t0: pointer to output vector t0
|
|
116
|
+
* - const polyvecl *s1: pointer to output vector s1
|
|
117
|
+
* - const polyveck *s2: pointer to output vector s2
|
|
118
|
+
* - uint8_t sk[]: byte array containing bit-packed sk
|
|
119
|
+
**************************************************/
|
|
120
|
+
void PQCLEAN_MLDSA65_CLEAN_unpack_sk(uint8_t rho[SEEDBYTES],
|
|
121
|
+
uint8_t tr[TRBYTES],
|
|
122
|
+
uint8_t key[SEEDBYTES],
|
|
123
|
+
polyveck *t0,
|
|
124
|
+
polyvecl *s1,
|
|
125
|
+
polyveck *s2,
|
|
126
|
+
const uint8_t sk[PQCLEAN_MLDSA65_CLEAN_CRYPTO_SECRETKEYBYTES]) {
|
|
127
|
+
unsigned int i;
|
|
128
|
+
|
|
129
|
+
for (i = 0; i < SEEDBYTES; ++i) {
|
|
130
|
+
rho[i] = sk[i];
|
|
131
|
+
}
|
|
132
|
+
sk += SEEDBYTES;
|
|
133
|
+
|
|
134
|
+
for (i = 0; i < SEEDBYTES; ++i) {
|
|
135
|
+
key[i] = sk[i];
|
|
136
|
+
}
|
|
137
|
+
sk += SEEDBYTES;
|
|
138
|
+
|
|
139
|
+
for (i = 0; i < TRBYTES; ++i) {
|
|
140
|
+
tr[i] = sk[i];
|
|
141
|
+
}
|
|
142
|
+
sk += TRBYTES;
|
|
143
|
+
|
|
144
|
+
for (i = 0; i < L; ++i) {
|
|
145
|
+
PQCLEAN_MLDSA65_CLEAN_polyeta_unpack(&s1->vec[i], sk + i * POLYETA_PACKEDBYTES);
|
|
146
|
+
}
|
|
147
|
+
sk += L * POLYETA_PACKEDBYTES;
|
|
148
|
+
|
|
149
|
+
for (i = 0; i < K; ++i) {
|
|
150
|
+
PQCLEAN_MLDSA65_CLEAN_polyeta_unpack(&s2->vec[i], sk + i * POLYETA_PACKEDBYTES);
|
|
151
|
+
}
|
|
152
|
+
sk += K * POLYETA_PACKEDBYTES;
|
|
153
|
+
|
|
154
|
+
for (i = 0; i < K; ++i) {
|
|
155
|
+
PQCLEAN_MLDSA65_CLEAN_polyt0_unpack(&t0->vec[i], sk + i * POLYT0_PACKEDBYTES);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/*************************************************
|
|
160
|
+
* Name: PQCLEAN_MLDSA65_CLEAN_pack_sig
|
|
161
|
+
*
|
|
162
|
+
* Description: Bit-pack signature sig = (c, z, h).
|
|
163
|
+
*
|
|
164
|
+
* Arguments: - uint8_t sig[]: output byte array
|
|
165
|
+
* - const uint8_t *c: pointer to challenge hash length SEEDBYTES
|
|
166
|
+
* - const polyvecl *z: pointer to vector z
|
|
167
|
+
* - const polyveck *h: pointer to hint vector h
|
|
168
|
+
**************************************************/
|
|
169
|
+
void PQCLEAN_MLDSA65_CLEAN_pack_sig(uint8_t sig[PQCLEAN_MLDSA65_CLEAN_CRYPTO_BYTES],
|
|
170
|
+
const uint8_t c[CTILDEBYTES],
|
|
171
|
+
const polyvecl *z,
|
|
172
|
+
const polyveck *h) {
|
|
173
|
+
unsigned int i, j, k;
|
|
174
|
+
|
|
175
|
+
for (i = 0; i < CTILDEBYTES; ++i) {
|
|
176
|
+
sig[i] = c[i];
|
|
177
|
+
}
|
|
178
|
+
sig += CTILDEBYTES;
|
|
179
|
+
|
|
180
|
+
for (i = 0; i < L; ++i) {
|
|
181
|
+
PQCLEAN_MLDSA65_CLEAN_polyz_pack(sig + i * POLYZ_PACKEDBYTES, &z->vec[i]);
|
|
182
|
+
}
|
|
183
|
+
sig += L * POLYZ_PACKEDBYTES;
|
|
184
|
+
|
|
185
|
+
/* Encode h */
|
|
186
|
+
for (i = 0; i < OMEGA + K; ++i) {
|
|
187
|
+
sig[i] = 0;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
k = 0;
|
|
191
|
+
for (i = 0; i < K; ++i) {
|
|
192
|
+
for (j = 0; j < N; ++j) {
|
|
193
|
+
if (h->vec[i].coeffs[j] != 0) {
|
|
194
|
+
sig[k++] = (uint8_t) j;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
sig[OMEGA + i] = (uint8_t) k;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/*************************************************
|
|
203
|
+
* Name: PQCLEAN_MLDSA65_CLEAN_unpack_sig
|
|
204
|
+
*
|
|
205
|
+
* Description: Unpack signature sig = (c, z, h).
|
|
206
|
+
*
|
|
207
|
+
* Arguments: - uint8_t *c: pointer to output challenge hash
|
|
208
|
+
* - polyvecl *z: pointer to output vector z
|
|
209
|
+
* - polyveck *h: pointer to output hint vector h
|
|
210
|
+
* - const uint8_t sig[]: byte array containing
|
|
211
|
+
* bit-packed signature
|
|
212
|
+
*
|
|
213
|
+
* Returns 1 in case of malformed signature; otherwise 0.
|
|
214
|
+
**************************************************/
|
|
215
|
+
int PQCLEAN_MLDSA65_CLEAN_unpack_sig(uint8_t c[CTILDEBYTES],
|
|
216
|
+
polyvecl *z,
|
|
217
|
+
polyveck *h,
|
|
218
|
+
const uint8_t sig[PQCLEAN_MLDSA65_CLEAN_CRYPTO_BYTES]) {
|
|
219
|
+
unsigned int i, j, k;
|
|
220
|
+
|
|
221
|
+
for (i = 0; i < CTILDEBYTES; ++i) {
|
|
222
|
+
c[i] = sig[i];
|
|
223
|
+
}
|
|
224
|
+
sig += CTILDEBYTES;
|
|
225
|
+
|
|
226
|
+
for (i = 0; i < L; ++i) {
|
|
227
|
+
PQCLEAN_MLDSA65_CLEAN_polyz_unpack(&z->vec[i], sig + i * POLYZ_PACKEDBYTES);
|
|
228
|
+
}
|
|
229
|
+
sig += L * POLYZ_PACKEDBYTES;
|
|
230
|
+
|
|
231
|
+
/* Decode h */
|
|
232
|
+
k = 0;
|
|
233
|
+
for (i = 0; i < K; ++i) {
|
|
234
|
+
for (j = 0; j < N; ++j) {
|
|
235
|
+
h->vec[i].coeffs[j] = 0;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (sig[OMEGA + i] < k || sig[OMEGA + i] > OMEGA) {
|
|
239
|
+
return 1;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
for (j = k; j < sig[OMEGA + i]; ++j) {
|
|
243
|
+
/* Coefficients are ordered for strong unforgeability */
|
|
244
|
+
if (j > k && sig[j] <= sig[j - 1]) {
|
|
245
|
+
return 1;
|
|
246
|
+
}
|
|
247
|
+
h->vec[i].coeffs[sig[j]] = 1;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
k = sig[OMEGA + i];
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/* Extra indices are zero for strong unforgeability */
|
|
254
|
+
for (j = k; j < OMEGA; ++j) {
|
|
255
|
+
if (sig[j]) {
|
|
256
|
+
return 1;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return 0;
|
|
261
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#ifndef PQCLEAN_MLDSA65_CLEAN_PACKING_H
|
|
2
|
+
#define PQCLEAN_MLDSA65_CLEAN_PACKING_H
|
|
3
|
+
#include "params.h"
|
|
4
|
+
#include "polyvec.h"
|
|
5
|
+
#include <stdint.h>
|
|
6
|
+
|
|
7
|
+
void PQCLEAN_MLDSA65_CLEAN_pack_pk(uint8_t pk[PQCLEAN_MLDSA65_CLEAN_CRYPTO_PUBLICKEYBYTES], const uint8_t rho[SEEDBYTES], const polyveck *t1);
|
|
8
|
+
|
|
9
|
+
void PQCLEAN_MLDSA65_CLEAN_pack_sk(uint8_t sk[PQCLEAN_MLDSA65_CLEAN_CRYPTO_SECRETKEYBYTES],
|
|
10
|
+
const uint8_t rho[SEEDBYTES],
|
|
11
|
+
const uint8_t tr[TRBYTES],
|
|
12
|
+
const uint8_t key[SEEDBYTES],
|
|
13
|
+
const polyveck *t0,
|
|
14
|
+
const polyvecl *s1,
|
|
15
|
+
const polyveck *s2);
|
|
16
|
+
|
|
17
|
+
void PQCLEAN_MLDSA65_CLEAN_pack_sig(uint8_t sig[PQCLEAN_MLDSA65_CLEAN_CRYPTO_BYTES], const uint8_t c[CTILDEBYTES], const polyvecl *z, const polyveck *h);
|
|
18
|
+
|
|
19
|
+
void PQCLEAN_MLDSA65_CLEAN_unpack_pk(uint8_t rho[SEEDBYTES], polyveck *t1, const uint8_t pk[PQCLEAN_MLDSA65_CLEAN_CRYPTO_PUBLICKEYBYTES]);
|
|
20
|
+
|
|
21
|
+
void PQCLEAN_MLDSA65_CLEAN_unpack_sk(uint8_t rho[SEEDBYTES],
|
|
22
|
+
uint8_t tr[TRBYTES],
|
|
23
|
+
uint8_t key[SEEDBYTES],
|
|
24
|
+
polyveck *t0,
|
|
25
|
+
polyvecl *s1,
|
|
26
|
+
polyveck *s2,
|
|
27
|
+
const uint8_t sk[PQCLEAN_MLDSA65_CLEAN_CRYPTO_SECRETKEYBYTES]);
|
|
28
|
+
|
|
29
|
+
int PQCLEAN_MLDSA65_CLEAN_unpack_sig(uint8_t c[CTILDEBYTES], polyvecl *z, polyveck *h, const uint8_t sig[PQCLEAN_MLDSA65_CLEAN_CRYPTO_BYTES]);
|
|
30
|
+
|
|
31
|
+
#endif
|