toxcore/other/fun/strkey.c
iphydf 895a6af122
cleanup: Remove NaCl support.
We now depend on libsodium unconditionally. Future work will require
functions from libsodium, and nobody we're aware of uses the nacl build
for anything other than making sure it still works on CI.
2023-12-25 00:36:38 +00:00

152 lines
4.1 KiB
C

/* strkey -- String in Public Key
*
* Generates Tox's key pairs, checking if a certain string is in the public key.
*
* Requires sodium library.
*
* There seem to be some problems with the code working on Windows -- it works
* when built in debug mode with MinGW 4.8, but it doesn't work correctly when
* built in release.
*
* Usage: strkey <offset> <string>
*
* Offset - an integer specifying exact byte offset position of the string you
* are looking for within a public key. When offset is negative, the program
* just looks for the desired string being somewhere, doesn't matter where, in
* the public key.
*
* String - a hex string that you want to have in your public key. It must have
* an even number of letters, since every two hexes map to a single byte of
* the public key.
*
* Examples:
* strkey 0 0123
* Looks for a public key that begins with "0123".
*
* strkey 1 0123
* Looks for a public key that has "0123" starting at its second byte, i.e. "XX0123...".
*
* strkey 2 0123
* Looks for a public key that has "0123" starting at its third byte, i.e. "XXXX0123...".
* (each two hexes represent a single byte of a public key)
*
* strkey -1 AF57CC
* Looks for a public key that contains "AF57CC", regardless of its position.
*
* To compile with gcc and sodium: gcc strkey.c -o strkey -lsodium
*/
#include <stdio.h>
#include <string.h>
#include <sodium.h>
#include "../../toxcore/ccompat.h"
#define PRINT_TRIES_COUNT
static void print_key(unsigned char *key)
{
for (size_t i = 0; i < crypto_box_PUBLICKEYBYTES; ++i) {
if (key[i] < 16) {
fprintf(stdout, "0");
}
fprintf(stdout, "%hhX", key[i]);
}
}
int main(int argc, char *argv[])
{
unsigned char public_key[crypto_box_PUBLICKEYBYTES]; // null terminator
unsigned char secret_key[crypto_box_SECRETKEYBYTES];
long int offset = 0;
size_t len;
unsigned char desired_bin[crypto_box_PUBLICKEYBYTES]; // null terminator
if (argc == 3) {
offset = strtol(argv[1], nullptr, 10);
if (offset <= 0) {
fprintf(stderr, "strtol() failed to convert \"%s\" into an integer\n", argv[1]);
exit(1);
}
char *desired_hex = argv[2];
len = strlen(desired_hex);
if (len % 2 != 0) {
fprintf(stderr, "Desired key should have an even number of letters\n");
exit(1);
}
size_t block_length = (offset < 0 ? 0 : offset) + len / 2;
if (block_length > crypto_box_PUBLICKEYBYTES) {
fprintf(stderr, "The given key with the given offset exceed public key's length\n");
exit(1);
}
// convert hex to bin
char *pos = desired_hex;
size_t i;
for (i = 0; i < len; pos += 2) {
unsigned int value;
sscanf(pos, "%02x", &value);
desired_bin[i] = value;
++i;
}
} else {
fprintf(stdout, "Usage: executable <byte offset> <desired hex string with even number of letters>\n");
exit(1);
}
len /= 2;
#ifdef PRINT_TRIES_COUNT
long long unsigned int tries = 0;
#endif
if (offset < 0) {
int found = 0;
do {
#ifdef PRINT_TRIES_COUNT
++tries;
#endif
crypto_box_keypair(public_key, secret_key);
for (int i = 0; i <= crypto_box_PUBLICKEYBYTES - len; ++i) {
if (memcmp(public_key + i, desired_bin, len) == 0) {
found = 1;
break;
}
}
} while (!found);
} else {
unsigned char *p = public_key + offset;
do {
#ifdef PRINT_TRIES_COUNT
++tries;
#endif
crypto_box_keypair(public_key, secret_key);
} while (memcmp(p, desired_bin, len) != 0);
}
fprintf(stdout, "Public key: ");
print_key(public_key);
fprintf(stdout, "\n");
fprintf(stdout, "Private key: ");
print_key(secret_key);
fprintf(stdout, "\n");
#ifdef PRINT_TRIES_COUNT
fprintf(stdout, "Found the key pair on %llu try.\n", tries);
#endif
return 0;
}