summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/mlkem/mlkem1024.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/libcrypto/mlkem/mlkem1024.c173
1 files changed, 113 insertions, 60 deletions
diff --git a/src/lib/libcrypto/mlkem/mlkem1024.c b/src/lib/libcrypto/mlkem/mlkem1024.c
index f6fccdf6a8..26c4716539 100644
--- a/src/lib/libcrypto/mlkem/mlkem1024.c
+++ b/src/lib/libcrypto/mlkem/mlkem1024.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mlkem1024.c,v 1.6 2025/01/03 08:19:24 tb Exp $ */ 1/* $OpenBSD: mlkem1024.c,v 1.11 2025/05/21 02:18:11 kenjiro Exp $ */
2/* 2/*
3 * Copyright (c) 2024, Google Inc. 3 * Copyright (c) 2024, Google Inc.
4 * Copyright (c) 2024, Bob Beck <beck@obtuse.com> 4 * Copyright (c) 2024, Bob Beck <beck@obtuse.com>
@@ -612,6 +612,19 @@ vector_encode(uint8_t *out, const vector *a, int bits)
612 } 612 }
613} 613}
614 614
615/* Encodes an entire vector as above, but adding it to a CBB */
616static int
617vector_encode_cbb(CBB *cbb, const vector *a, int bits)
618{
619 uint8_t *encoded_vector;
620
621 if (!CBB_add_space(cbb, &encoded_vector, kEncodedVectorSize))
622 return 0;
623 vector_encode(encoded_vector, a, bits);
624
625 return 1;
626}
627
615/* 628/*
616 * scalar_decode parses |DEGREE * bits| bits from |in| into |DEGREE| values in 629 * scalar_decode parses |DEGREE * bits| bits from |in| into |DEGREE| values in
617 * |out|. It returns one on success and zero if any parsed value is >= 630 * |out|. It returns one on success and zero if any parsed value is >=
@@ -793,6 +806,8 @@ struct public_key {
793 matrix m; 806 matrix m;
794}; 807};
795 808
809CTASSERT(sizeof(struct MLKEM1024_public_key) == sizeof(struct public_key));
810
796static struct public_key * 811static struct public_key *
797public_key_1024_from_external(const struct MLKEM1024_public_key *external) 812public_key_1024_from_external(const struct MLKEM1024_public_key *external)
798{ 813{
@@ -805,6 +820,8 @@ struct private_key {
805 uint8_t fo_failure_secret[32]; 820 uint8_t fo_failure_secret[32];
806}; 821};
807 822
823CTASSERT(sizeof(struct MLKEM1024_private_key) == sizeof(struct private_key));
824
808static struct private_key * 825static struct private_key *
809private_key_1024_from_external(const struct MLKEM1024_private_key *external) 826private_key_1024_from_external(const struct MLKEM1024_private_key *external)
810{ 827{
@@ -815,7 +832,7 @@ private_key_1024_from_external(const struct MLKEM1024_private_key *external)
815 * Calls |MLKEM1024_generate_key_external_entropy| with random bytes from 832 * Calls |MLKEM1024_generate_key_external_entropy| with random bytes from
816 * |RAND_bytes|. 833 * |RAND_bytes|.
817 */ 834 */
818void 835int
819MLKEM1024_generate_key(uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES], 836MLKEM1024_generate_key(uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES],
820 uint8_t optional_out_seed[MLKEM_SEED_BYTES], 837 uint8_t optional_out_seed[MLKEM_SEED_BYTES],
821 struct MLKEM1024_private_key *out_private_key) 838 struct MLKEM1024_private_key *out_private_key)
@@ -825,7 +842,7 @@ MLKEM1024_generate_key(uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES
825 entropy_buf; 842 entropy_buf;
826 843
827 arc4random_buf(entropy, MLKEM_SEED_BYTES); 844 arc4random_buf(entropy, MLKEM_SEED_BYTES);
828 MLKEM1024_generate_key_external_entropy(out_encoded_public_key, 845 return MLKEM1024_generate_key_external_entropy(out_encoded_public_key,
829 out_private_key, entropy); 846 out_private_key, entropy);
830} 847}
831LCRYPTO_ALIAS(MLKEM1024_generate_key); 848LCRYPTO_ALIAS(MLKEM1024_generate_key);
@@ -839,29 +856,20 @@ MLKEM1024_private_key_from_seed(struct MLKEM1024_private_key *out_private_key,
839 if (seed_len != MLKEM_SEED_BYTES) { 856 if (seed_len != MLKEM_SEED_BYTES) {
840 return 0; 857 return 0;
841 } 858 }
842 MLKEM1024_generate_key_external_entropy(public_key_bytes, 859 return MLKEM1024_generate_key_external_entropy(public_key_bytes,
843 out_private_key, seed); 860 out_private_key, seed);
844
845 return 1;
846} 861}
847LCRYPTO_ALIAS(MLKEM1024_private_key_from_seed); 862LCRYPTO_ALIAS(MLKEM1024_private_key_from_seed);
848 863
849static int 864static int
850mlkem_marshal_public_key(CBB *out, const struct public_key *pub) 865mlkem_marshal_public_key(CBB *out, const struct public_key *pub)
851{ 866{
852 uint8_t *vector_output; 867 if (!vector_encode_cbb(out, &pub->t, kLog2Prime))
853
854 if (!CBB_add_space(out, &vector_output, kEncodedVectorSize)) {
855 return 0; 868 return 0;
856 } 869 return CBB_add_bytes(out, pub->rho, sizeof(pub->rho));
857 vector_encode(vector_output, &pub->t, kLog2Prime);
858 if (!CBB_add_bytes(out, pub->rho, sizeof(pub->rho))) {
859 return 0;
860 }
861 return 1;
862} 870}
863 871
864void 872int
865MLKEM1024_generate_key_external_entropy( 873MLKEM1024_generate_key_external_entropy(
866 uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES], 874 uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES],
867 struct MLKEM1024_private_key *out_private_key, 875 struct MLKEM1024_private_key *out_private_key,
@@ -875,7 +883,9 @@ MLKEM1024_generate_key_external_entropy(
875 uint8_t hashed[64]; 883 uint8_t hashed[64];
876 vector error; 884 vector error;
877 CBB cbb; 885 CBB cbb;
886 int ret = 0;
878 887
888 memset(&cbb, 0, sizeof(CBB));
879 memcpy(augmented_seed, entropy, 32); 889 memcpy(augmented_seed, entropy, 32);
880 augmented_seed[32] = RANK1024; 890 augmented_seed[32] = RANK1024;
881 hash_g(hashed, augmented_seed, 33); 891 hash_g(hashed, augmented_seed, 33);
@@ -890,16 +900,23 @@ MLKEM1024_generate_key_external_entropy(
890 matrix_mult_transpose(&priv->pub.t, &priv->pub.m, &priv->s); 900 matrix_mult_transpose(&priv->pub.t, &priv->pub.m, &priv->s);
891 vector_add(&priv->pub.t, &error); 901 vector_add(&priv->pub.t, &error);
892 902
893 /* XXX - error checking. */ 903 if (!CBB_init_fixed(&cbb, out_encoded_public_key,
894 CBB_init_fixed(&cbb, out_encoded_public_key, MLKEM1024_PUBLIC_KEY_BYTES); 904 MLKEM1024_PUBLIC_KEY_BYTES))
895 if (!mlkem_marshal_public_key(&cbb, &priv->pub)) { 905 goto err;
896 abort(); 906
897 } 907 if (!mlkem_marshal_public_key(&cbb, &priv->pub))
898 CBB_cleanup(&cbb); 908 goto err;
899 909
900 hash_h(priv->pub.public_key_hash, out_encoded_public_key, 910 hash_h(priv->pub.public_key_hash, out_encoded_public_key,
901 MLKEM1024_PUBLIC_KEY_BYTES); 911 MLKEM1024_PUBLIC_KEY_BYTES);
902 memcpy(priv->fo_failure_secret, entropy + 32, 32); 912 memcpy(priv->fo_failure_secret, entropy + 32, 32);
913
914 ret = 1;
915
916 err:
917 CBB_cleanup(&cbb);
918
919 return ret;
903} 920}
904 921
905void 922void
@@ -1045,11 +1062,26 @@ MLKEM1024_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
1045LCRYPTO_ALIAS(MLKEM1024_decap); 1062LCRYPTO_ALIAS(MLKEM1024_decap);
1046 1063
1047int 1064int
1048MLKEM1024_marshal_public_key(CBB *out, 1065MLKEM1024_marshal_public_key(uint8_t **output, size_t *output_len,
1049 const struct MLKEM1024_public_key *public_key) 1066 const struct MLKEM1024_public_key *public_key)
1050{ 1067{
1051 return mlkem_marshal_public_key(out, 1068 int ret = 0;
1052 public_key_1024_from_external(public_key)); 1069 CBB cbb;
1070
1071 if (!CBB_init(&cbb, MLKEM1024_PUBLIC_KEY_BYTES))
1072 goto err;
1073 if (!mlkem_marshal_public_key(&cbb,
1074 public_key_1024_from_external(public_key)))
1075 goto err;
1076 if (!CBB_finish(&cbb, output, output_len))
1077 goto err;
1078
1079 ret = 1;
1080
1081 err:
1082 CBB_cleanup(&cbb);
1083
1084 return ret;
1053} 1085}
1054LCRYPTO_ALIAS(MLKEM1024_marshal_public_key); 1086LCRYPTO_ALIAS(MLKEM1024_marshal_public_key);
1055 1087
@@ -1062,10 +1094,11 @@ mlkem_parse_public_key_no_hash(struct public_key *pub, CBS *in)
1062{ 1094{
1063 CBS t_bytes; 1095 CBS t_bytes;
1064 1096
1065 if (!CBS_get_bytes(in, &t_bytes, kEncodedVectorSize) || 1097 if (!CBS_get_bytes(in, &t_bytes, kEncodedVectorSize))
1066 !vector_decode(&pub->t, CBS_data(&t_bytes), kLog2Prime)) {
1067 return 0; 1098 return 0;
1068 } 1099 if (!vector_decode(&pub->t, CBS_data(&t_bytes), kLog2Prime))
1100 return 0;
1101
1069 memcpy(pub->rho, CBS_data(in), sizeof(pub->rho)); 1102 memcpy(pub->rho, CBS_data(in), sizeof(pub->rho));
1070 if (!CBS_skip(in, sizeof(pub->rho))) 1103 if (!CBS_skip(in, sizeof(pub->rho)))
1071 return 0; 1104 return 0;
@@ -1074,64 +1107,84 @@ mlkem_parse_public_key_no_hash(struct public_key *pub, CBS *in)
1074} 1107}
1075 1108
1076int 1109int
1077MLKEM1024_parse_public_key(struct MLKEM1024_public_key *public_key, CBS *in) 1110MLKEM1024_parse_public_key(struct MLKEM1024_public_key *public_key,
1111 const uint8_t *input, size_t input_len)
1078{ 1112{
1079 struct public_key *pub = public_key_1024_from_external(public_key); 1113 struct public_key *pub = public_key_1024_from_external(public_key);
1080 CBS orig_in = *in; 1114 CBS cbs;
1081 1115
1082 if (!mlkem_parse_public_key_no_hash(pub, in) || 1116 CBS_init(&cbs, input, input_len);
1083 CBS_len(in) != 0) { 1117 if (!mlkem_parse_public_key_no_hash(pub, &cbs))
1084 return 0; 1118 return 0;
1085 } 1119 if (CBS_len(&cbs) != 0)
1086 hash_h(pub->public_key_hash, CBS_data(&orig_in), CBS_len(&orig_in)); 1120 return 0;
1121
1122 hash_h(pub->public_key_hash, input, input_len);
1123
1087 return 1; 1124 return 1;
1088} 1125}
1089LCRYPTO_ALIAS(MLKEM1024_parse_public_key); 1126LCRYPTO_ALIAS(MLKEM1024_parse_public_key);
1090 1127
1091int 1128int
1092MLKEM1024_marshal_private_key(CBB *out, 1129MLKEM1024_marshal_private_key(const struct MLKEM1024_private_key *private_key,
1093 const struct MLKEM1024_private_key *private_key) 1130 uint8_t **out_private_key, size_t *out_private_key_len)
1094{ 1131{
1095 const struct private_key *const priv = private_key_1024_from_external( 1132 const struct private_key *const priv = private_key_1024_from_external(
1096 private_key); 1133 private_key);
1097 uint8_t *s_output; 1134 CBB cbb;
1135 int ret = 0;
1098 1136
1099 if (!CBB_add_space(out, &s_output, kEncodedVectorSize)) { 1137 if (!CBB_init(&cbb, MLKEM1024_PRIVATE_KEY_BYTES))
1100 return 0; 1138 goto err;
1101 } 1139
1102 vector_encode(s_output, &priv->s, kLog2Prime); 1140 if (!vector_encode_cbb(&cbb, &priv->s, kLog2Prime))
1103 if (!mlkem_marshal_public_key(out, &priv->pub) || 1141 goto err;
1104 !CBB_add_bytes(out, priv->pub.public_key_hash, 1142 if (!mlkem_marshal_public_key(&cbb, &priv->pub))
1105 sizeof(priv->pub.public_key_hash)) || 1143 goto err;
1106 !CBB_add_bytes(out, priv->fo_failure_secret, 1144 if (!CBB_add_bytes(&cbb, priv->pub.public_key_hash,
1107 sizeof(priv->fo_failure_secret))) { 1145 sizeof(priv->pub.public_key_hash)))
1108 return 0; 1146 goto err;
1109 } 1147 if (!CBB_add_bytes(&cbb, priv->fo_failure_secret,
1110 return 1; 1148 sizeof(priv->fo_failure_secret)))
1149 goto err;
1150
1151 if (!CBB_finish(&cbb, out_private_key, out_private_key_len))
1152 goto err;
1153
1154 ret = 1;
1155
1156 err:
1157 CBB_cleanup(&cbb);
1158
1159 return ret;
1111} 1160}
1112 1161
1113int 1162int
1114MLKEM1024_parse_private_key(struct MLKEM1024_private_key *out_private_key, 1163MLKEM1024_parse_private_key(struct MLKEM1024_private_key *out_private_key,
1115 CBS *in) 1164 const uint8_t *input, size_t input_len)
1116{ 1165{
1117 struct private_key *const priv = private_key_1024_from_external( 1166 struct private_key *const priv = private_key_1024_from_external(
1118 out_private_key); 1167 out_private_key);
1119 CBS s_bytes; 1168 CBS cbs, s_bytes;
1120 1169
1121 if (!CBS_get_bytes(in, &s_bytes, kEncodedVectorSize) || 1170 CBS_init(&cbs, input, input_len);
1122 !vector_decode(&priv->s, CBS_data(&s_bytes), kLog2Prime) || 1171
1123 !mlkem_parse_public_key_no_hash(&priv->pub, in)) { 1172 if (!CBS_get_bytes(&cbs, &s_bytes, kEncodedVectorSize))
1124 return 0; 1173 return 0;
1125 } 1174 if (!vector_decode(&priv->s, CBS_data(&s_bytes), kLog2Prime))
1126 memcpy(priv->pub.public_key_hash, CBS_data(in), 1175 return 0;
1176 if (!mlkem_parse_public_key_no_hash(&priv->pub, &cbs))
1177 return 0;
1178
1179 memcpy(priv->pub.public_key_hash, CBS_data(&cbs),
1127 sizeof(priv->pub.public_key_hash)); 1180 sizeof(priv->pub.public_key_hash));
1128 if (!CBS_skip(in, sizeof(priv->pub.public_key_hash))) 1181 if (!CBS_skip(&cbs, sizeof(priv->pub.public_key_hash)))
1129 return 0; 1182 return 0;
1130 memcpy(priv->fo_failure_secret, CBS_data(in), 1183 memcpy(priv->fo_failure_secret, CBS_data(&cbs),
1131 sizeof(priv->fo_failure_secret)); 1184 sizeof(priv->fo_failure_secret));
1132 if (!CBS_skip(in, sizeof(priv->fo_failure_secret))) 1185 if (!CBS_skip(&cbs, sizeof(priv->fo_failure_secret)))
1133 return 0; 1186 return 0;
1134 if (CBS_len(in) != 0) 1187 if (CBS_len(&cbs) != 0)
1135 return 0; 1188 return 0;
1136 1189
1137 return 1; 1190 return 1;