diff options
Diffstat (limited to 'src/fs/fs_pseudonym.c')
-rw-r--r-- | src/fs/fs_pseudonym.c | 130 |
1 files changed, 92 insertions, 38 deletions
diff --git a/src/fs/fs_pseudonym.c b/src/fs/fs_pseudonym.c index 49a084199..36eaab6fa 100644 --- a/src/fs/fs_pseudonym.c +++ b/src/fs/fs_pseudonym.c | |||
@@ -104,9 +104,8 @@ static struct GNUNET_FS_pseudonym_DiscoveryHandle *disco_head; | |||
104 | static struct GNUNET_FS_pseudonym_DiscoveryHandle *disco_tail; | 104 | static struct GNUNET_FS_pseudonym_DiscoveryHandle *disco_tail; |
105 | 105 | ||
106 | /** | 106 | /** |
107 | * Pointer to indiate 'anonymous' pseudonym (global static, all | 107 | * Pointer to indiate 'anonymous' pseudonym (global static, |
108 | * zeros). We actually use pointer comparisson to detect the | 108 | * d=1, public key = G (generator). |
109 | * "anonymous" pseudonym handle. | ||
110 | */ | 109 | */ |
111 | static struct GNUNET_FS_PseudonymHandle anonymous; | 110 | static struct GNUNET_FS_PseudonymHandle anonymous; |
112 | 111 | ||
@@ -1019,6 +1018,68 @@ GNUNET_FS_pseudonym_create_from_existing_file (const char *filename) | |||
1019 | struct GNUNET_FS_PseudonymHandle * | 1018 | struct GNUNET_FS_PseudonymHandle * |
1020 | GNUNET_FS_pseudonym_get_anonymous_pseudonym_handle () | 1019 | GNUNET_FS_pseudonym_get_anonymous_pseudonym_handle () |
1021 | { | 1020 | { |
1021 | static int once; | ||
1022 | gcry_mpi_t d; | ||
1023 | size_t size; | ||
1024 | gcry_ctx_t ctx; | ||
1025 | int rc; | ||
1026 | gcry_mpi_t g_x; | ||
1027 | gcry_mpi_t g_y; | ||
1028 | gcry_mpi_point_t g; | ||
1029 | |||
1030 | if (once) | ||
1031 | return &anonymous; | ||
1032 | d = gcry_mpi_new (1); | ||
1033 | gcry_mpi_set_ui (d, 1); | ||
1034 | size = sizeof (anonymous.d); | ||
1035 | GNUNET_assert (0 == | ||
1036 | gcry_mpi_print (GCRYMPI_FMT_USG, anonymous.d, size, &size, | ||
1037 | d)); | ||
1038 | gcry_mpi_release (d); | ||
1039 | adjust (anonymous.d, size, sizeof (anonymous.d)); | ||
1040 | |||
1041 | /* create basic ECC context */ | ||
1042 | if (0 != (rc = gcry_mpi_ec_new (&ctx, NULL, "NIST P-256"))) | ||
1043 | { | ||
1044 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, | ||
1045 | "gcry_mpi_ec_new", rc); | ||
1046 | return NULL; | ||
1047 | } | ||
1048 | |||
1049 | g = gcry_mpi_ec_get_point ("g", ctx, 0); | ||
1050 | g_x = gcry_mpi_new (256); | ||
1051 | g_y = gcry_mpi_new (256); | ||
1052 | gcry_mpi_ec_get_affine (g_x, g_y, g, ctx); | ||
1053 | gcry_mpi_point_release (g); | ||
1054 | gcry_ctx_release (ctx); | ||
1055 | |||
1056 | /* store g_x/g_y in public key */ | ||
1057 | size = sizeof (anonymous.public_key.q_x); | ||
1058 | if (0 != | ||
1059 | gcry_mpi_print (GCRYMPI_FMT_USG, anonymous.public_key.q_x, size, &size, | ||
1060 | g_x)) | ||
1061 | { | ||
1062 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc); | ||
1063 | gcry_mpi_release (g_x); | ||
1064 | gcry_mpi_release (g_y); | ||
1065 | return NULL; | ||
1066 | } | ||
1067 | adjust (anonymous.public_key.q_x, size, sizeof (anonymous.public_key.q_x)); | ||
1068 | gcry_mpi_release (g_x); | ||
1069 | |||
1070 | size = sizeof (anonymous.public_key.q_y); | ||
1071 | if (0 != | ||
1072 | gcry_mpi_print (GCRYMPI_FMT_USG, anonymous.public_key.q_y, size, &size, | ||
1073 | g_y)) | ||
1074 | { | ||
1075 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_print", rc); | ||
1076 | gcry_mpi_release (g_y); | ||
1077 | return NULL; | ||
1078 | } | ||
1079 | adjust (anonymous.public_key.q_y, size, sizeof (anonymous.public_key.q_y)); | ||
1080 | gcry_mpi_release (g_y); | ||
1081 | |||
1082 | once = 1; | ||
1022 | return &anonymous; | 1083 | return &anonymous; |
1023 | } | 1084 | } |
1024 | 1085 | ||
@@ -1122,21 +1183,13 @@ GNUNET_FS_pseudonym_sign (struct GNUNET_FS_PseudonymHandle *ph, | |||
1122 | int rc; | 1183 | int rc; |
1123 | 1184 | ||
1124 | /* get private key 'd' from pseudonym */ | 1185 | /* get private key 'd' from pseudonym */ |
1125 | if (&anonymous == ph) | 1186 | size = sizeof (ph->d); |
1126 | { | 1187 | if (0 != (rc = gcry_mpi_scan (&d, GCRYMPI_FMT_USG, |
1127 | d = gcry_mpi_new (0); | 1188 | &ph->d, |
1128 | gcry_mpi_set_ui (d, 0); | 1189 | size, &size))) |
1129 | } | ||
1130 | else | ||
1131 | { | 1190 | { |
1132 | size = sizeof (ph->d); | 1191 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); |
1133 | if (0 != (rc = gcry_mpi_scan (&d, GCRYMPI_FMT_USG, | 1192 | return GNUNET_SYSERR; |
1134 | &ph->d, | ||
1135 | size, &size))) | ||
1136 | { | ||
1137 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); | ||
1138 | return GNUNET_SYSERR; | ||
1139 | } | ||
1140 | } | 1193 | } |
1141 | /* get 'x' value from signing key */ | 1194 | /* get 'x' value from signing key */ |
1142 | size = sizeof (struct GNUNET_HashCode); | 1195 | size = sizeof (struct GNUNET_HashCode); |
@@ -1159,9 +1212,9 @@ GNUNET_FS_pseudonym_sign (struct GNUNET_FS_PseudonymHandle *ph, | |||
1159 | return GNUNET_SYSERR; | 1212 | return GNUNET_SYSERR; |
1160 | } | 1213 | } |
1161 | 1214 | ||
1162 | /* calculate dx = d + h mod n */ | 1215 | /* calculate dh = d * h mod n */ |
1163 | dh = gcry_mpi_new (256); | 1216 | dh = gcry_mpi_new (256); |
1164 | gcry_mpi_addm (dh, d, h, n); | 1217 | gcry_mpi_mulm (dh, d, h, n); |
1165 | gcry_mpi_release (d); | 1218 | gcry_mpi_release (d); |
1166 | gcry_mpi_release (h); | 1219 | gcry_mpi_release (h); |
1167 | gcry_mpi_release (n); | 1220 | gcry_mpi_release (n); |
@@ -1297,7 +1350,7 @@ get_context_from_pseudonym (struct GNUNET_FS_PseudonymIdentifier *pseudonym) | |||
1297 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc); /* erroff gives more info */ | 1350 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc); /* erroff gives more info */ |
1298 | return NULL; | 1351 | return NULL; |
1299 | } | 1352 | } |
1300 | /* initialize 'ctx' with 'q' = 0 */ | 1353 | /* FIXME: initialize 'ctx' with 'q' = G */ |
1301 | zero = gcry_mpi_new (0); | 1354 | zero = gcry_mpi_new (0); |
1302 | gcry_mpi_set_ui (zero, 0); | 1355 | gcry_mpi_set_ui (zero, 0); |
1303 | q = gcry_mpi_point_new (0); | 1356 | q = gcry_mpi_point_new (0); |
@@ -1346,7 +1399,7 @@ get_context_from_pseudonym (struct GNUNET_FS_PseudonymIdentifier *pseudonym) | |||
1346 | * @param pseudonym the public key (dQ in ECDSA) | 1399 | * @param pseudonym the public key (dQ in ECDSA) |
1347 | * @param signing_key input to derive 'h' (see section 2.4 of #2564) | 1400 | * @param signing_key input to derive 'h' (see section 2.4 of #2564) |
1348 | * @param verification_key resulting public key to verify the signature | 1401 | * @param verification_key resulting public key to verify the signature |
1349 | * created from the '(d+h)' of 'pseudonym' and the 'signing_key'; | 1402 | * created from the '(d*h)' of 'pseudonym' and the 'signing_key'; |
1350 | * the value stored here can then be given to GNUNET_FS_pseudonym_verify. | 1403 | * the value stored here can then be given to GNUNET_FS_pseudonym_verify. |
1351 | * @return GNUNET_OK on success, GNUNET_SYSERR on error | 1404 | * @return GNUNET_OK on success, GNUNET_SYSERR on error |
1352 | */ | 1405 | */ |
@@ -1359,12 +1412,12 @@ GNUNET_FS_pseudonym_derive_verification_key (struct GNUNET_FS_PseudonymIdentifie | |||
1359 | size_t size; | 1412 | size_t size; |
1360 | int rc; | 1413 | int rc; |
1361 | gcry_ctx_t ctx; | 1414 | gcry_ctx_t ctx; |
1362 | gcry_mpi_point_t g; | ||
1363 | gcry_mpi_point_t q; | 1415 | gcry_mpi_point_t q; |
1364 | gcry_mpi_point_t hg; | ||
1365 | gcry_mpi_point_t v; | 1416 | gcry_mpi_point_t v; |
1366 | gcry_mpi_t v_x; | 1417 | gcry_mpi_t v_x; |
1367 | gcry_mpi_t v_y; | 1418 | gcry_mpi_t v_y; |
1419 | gcry_mpi_t h_mod_n; | ||
1420 | gcry_mpi_t n; /* n from P-256 */ | ||
1368 | 1421 | ||
1369 | /* get 'h' value from signing key */ | 1422 | /* get 'h' value from signing key */ |
1370 | size = sizeof (struct GNUNET_HashCode); | 1423 | size = sizeof (struct GNUNET_HashCode); |
@@ -1381,22 +1434,26 @@ GNUNET_FS_pseudonym_derive_verification_key (struct GNUNET_FS_PseudonymIdentifie | |||
1381 | gcry_mpi_release (h); | 1434 | gcry_mpi_release (h); |
1382 | return GNUNET_SYSERR; | 1435 | return GNUNET_SYSERR; |
1383 | } | 1436 | } |
1384 | /* get G */ | 1437 | /* initialize 'n' from P-256; hex copied from libgcrypt code */ |
1385 | g = gcry_mpi_ec_get_point ("g", ctx, 0); | 1438 | if (0 != (rc = gcry_mpi_scan (&n, GCRYMPI_FMT_HEX, |
1386 | 1439 | "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 0, NULL))) | |
1387 | /* then call the 'multiply' function, to compute the product hG */ | 1440 | { |
1388 | hg = gcry_mpi_point_new (0); | 1441 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); |
1389 | gcry_mpi_ec_mul (hg, h, g, ctx); | 1442 | gcry_mpi_release (h); |
1390 | gcry_mpi_point_release (g); | 1443 | return GNUNET_SYSERR; |
1444 | } | ||
1445 | h_mod_n = gcry_mpi_new (0); | ||
1446 | gcry_mpi_mod (h_mod_n, h, n); | ||
1391 | gcry_mpi_release (h); | 1447 | gcry_mpi_release (h); |
1392 | 1448 | ||
1393 | /* get Q = dG from 'pseudonym' */ | 1449 | /* get Q = dG from 'pseudonym' */ |
1394 | q = gcry_mpi_ec_get_point ("q", ctx, 0); | 1450 | q = gcry_mpi_ec_get_point ("q", ctx, 0); |
1395 | /* calculate V = Q + hG = dG + hG = (d + h)G*/ | 1451 | /* calculate V = hQ = hdG */ |
1396 | v = gcry_mpi_point_new (0); | 1452 | v = gcry_mpi_point_new (0); |
1397 | gcry_mpi_ec_add (v, q, hg, ctx); | ||
1398 | gcry_mpi_point_release (hg); | ||
1399 | 1453 | ||
1454 | gcry_mpi_ec_mul (v, h_mod_n, q, ctx); | ||
1455 | gcry_mpi_release (h_mod_n); | ||
1456 | |||
1400 | /* store 'v' point in "verification_key" */ | 1457 | /* store 'v' point in "verification_key" */ |
1401 | v_x = gcry_mpi_new (256); | 1458 | v_x = gcry_mpi_new (256); |
1402 | v_y = gcry_mpi_new (256); | 1459 | v_y = gcry_mpi_new (256); |
@@ -1566,11 +1623,8 @@ void | |||
1566 | GNUNET_FS_pseudonym_get_identifier (struct GNUNET_FS_PseudonymHandle *ph, | 1623 | GNUNET_FS_pseudonym_get_identifier (struct GNUNET_FS_PseudonymHandle *ph, |
1567 | struct GNUNET_FS_PseudonymIdentifier *pseudonym) | 1624 | struct GNUNET_FS_PseudonymIdentifier *pseudonym) |
1568 | { | 1625 | { |
1569 | if (&anonymous == ph) | 1626 | memcpy (pseudonym, &ph->public_key, |
1570 | memset (pseudonym, 0, sizeof (struct GNUNET_FS_PseudonymIdentifier)); | 1627 | sizeof (struct GNUNET_FS_PseudonymIdentifier)); |
1571 | else | ||
1572 | memcpy (pseudonym, &ph->public_key, | ||
1573 | sizeof (struct GNUNET_FS_PseudonymIdentifier)); | ||
1574 | } | 1628 | } |
1575 | 1629 | ||
1576 | 1630 | ||