mirror of
https://github.com/cathugger/mkp224o.git
synced 2025-04-20 22:09:10 +00:00
prototype of trustless mining
This commit is contained in:
parent
d202229a43
commit
bd3b8d5881
5 changed files with 277 additions and 11 deletions
26
README.md
26
README.md
|
@ -3,6 +3,32 @@
|
||||||
This tool generates vanity ed25519 ([hidden service version 3][v3],
|
This tool generates vanity ed25519 ([hidden service version 3][v3],
|
||||||
formely known as proposal 224) onion addresses.
|
formely known as proposal 224) onion addresses.
|
||||||
|
|
||||||
|
### What is this fork?
|
||||||
|
This is my shot at implementing [trustless mining](https://github.com/cathugger/mkp224o/issues/60).
|
||||||
|
It's a garbage implementation, but it (kinda?) works.
|
||||||
|
|
||||||
|
#### Usage
|
||||||
|
```
|
||||||
|
$ ./mkp224o --genbase out/base.priv out/base.pub
|
||||||
|
writing private base key to 'out/base.priv'
|
||||||
|
writing public base key to 'out/base.pub'
|
||||||
|
done.
|
||||||
|
|
||||||
|
$ ./mkp224o -n 1 -d out -Z --basekey out/base.pub zzz
|
||||||
|
|
||||||
|
$ ./mkp224o --combine out/base.priv out/zzz*.onion/hs_ed25519_secret_key
|
||||||
|
new pk: [...]
|
||||||
|
saving to out/zzzkzmpje34nnp2yvgz7slr7rgpajzlpihsr3rpzgmekrjosnpprf2id.onion/hs_ed25519_secret_key.fixed
|
||||||
|
|
||||||
|
$ cp out/zzz*.onion/hs_ed25519_secret_key.fixed /var/lib/tor/hidden_service/hs_ed25519_secret_key
|
||||||
|
```
|
||||||
|
|
||||||
|
#### the ugly
|
||||||
|
* i'm an amateur, the math might not check out
|
||||||
|
* horrible code organization - i'm not familiar with this style of codebases at all
|
||||||
|
* depends on ed25519-donna
|
||||||
|
* only works with slow key generation (-Z)
|
||||||
|
|
||||||
### Requirements
|
### Requirements
|
||||||
|
|
||||||
* C99 compatible compiler (gcc and clang should work)
|
* C99 compatible compiler (gcc and clang should work)
|
||||||
|
|
200
main.c
200
main.c
|
@ -132,6 +132,13 @@ static void printhelp(FILE *out,const char *progname)
|
||||||
#endif
|
#endif
|
||||||
" --rawyaml raw (unprefixed) public/secret keys for -y/-Y\n"
|
" --rawyaml raw (unprefixed) public/secret keys for -y/-Y\n"
|
||||||
" (may be useful for tor controller API)\n"
|
" (may be useful for tor controller API)\n"
|
||||||
|
" --basekey base.pub\n"
|
||||||
|
" trustless mining: the private keys found will need\n"
|
||||||
|
" to be --combine'd with base.priv before use\n"
|
||||||
|
" --genbase base.priv base.pub\n"
|
||||||
|
" generate base keys for trustless mining\n"
|
||||||
|
" --combine base.priv hs_secret_key\n"
|
||||||
|
" combine a mined hs_secret key with a base key\n"
|
||||||
" -h, --help, --usage print help to stdout and quit\n"
|
" -h, --help, --usage print help to stdout and quit\n"
|
||||||
" -V, --version print version information to stdout and exit\n"
|
" -V, --version print version information to stdout and exit\n"
|
||||||
,progname,progname);
|
,progname,progname);
|
||||||
|
@ -262,11 +269,160 @@ enum worker_type {
|
||||||
WT_BATCH,
|
WT_BATCH,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// i'm so sorry for including an implementation header
|
||||||
|
// i didn't find another way to get access to the functions
|
||||||
|
#include "ed25519/ed25519_impl_pre.h"
|
||||||
|
static void genbase(const char *privpath, const char *pubpath)
|
||||||
|
{
|
||||||
|
u8 base_sk[32];
|
||||||
|
u8 base_pk[32];
|
||||||
|
hash_512bits base_extsk;
|
||||||
|
ge25519 ALIGN(16) A;
|
||||||
|
bignum256modm ALIGN(16) base;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
randombytes(base_sk, sizeof base_sk);
|
||||||
|
ed25519_seckey_expand(base_extsk, base_sk);
|
||||||
|
expand256_modm(base, base_extsk, 32);
|
||||||
|
ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, base);
|
||||||
|
ge25519_pack(base_pk, &A);
|
||||||
|
|
||||||
|
printf("writing private base key to '%s'\n", privpath);
|
||||||
|
fp = fopen(privpath, "w");
|
||||||
|
if (!fp) {
|
||||||
|
perror("couldn't open");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (fwrite(base_sk, 1, 32, fp) != 32) {
|
||||||
|
perror("write");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
printf("writing public base key to '%s'\n", pubpath);
|
||||||
|
fp = fopen(pubpath, "w");
|
||||||
|
if (!fp) {
|
||||||
|
perror("couldn't open");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (fwrite(base_pk, 1, 32, fp) != 32) {
|
||||||
|
perror("write");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
puts("done.");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void combine(const char *privpath, const char *hs_secretkey)
|
||||||
|
{
|
||||||
|
u8 base_sk[32], secret[96];
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
fp = fopen(hs_secretkey, "r");
|
||||||
|
if (fp == NULL) {
|
||||||
|
perror("failed to open hs_secret_key");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (fread(secret, 1, 96, fp) != 96) {
|
||||||
|
perror("failed to read hs_secret_key");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (memcmp(secret, "== ed25519v1-secret: type0 ==\0\0\0", 32) != 0) {
|
||||||
|
fprintf(stderr, "invalid hs_secret_key format.\nare you sure you picked the right file?\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
fp = fopen(privpath, "r");
|
||||||
|
if (fp == NULL) {
|
||||||
|
perror("failed to open base.priv");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (fread(base_sk, 1, sizeof base_sk, fp) != sizeof base_sk) {
|
||||||
|
perror("failed to read base.priv");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
u8 pk[32];
|
||||||
|
|
||||||
|
hash_512bits base_extsk;
|
||||||
|
ed25519_seckey_expand(base_extsk, base_sk);
|
||||||
|
|
||||||
|
bignum256modm ALIGN(16) base;
|
||||||
|
expand256_modm(base, base_extsk, 32);
|
||||||
|
|
||||||
|
ge25519 ALIGN(16) A, B;
|
||||||
|
ge25519_scalarmult_base_niels(&B, ge25519_niels_base_multiples, base);
|
||||||
|
u8 base_pk[32];
|
||||||
|
ge25519_pack(base_pk, &B);
|
||||||
|
ge25519_unpack_negative_vartime(&B, base_pk);
|
||||||
|
ge25519_pack(base_pk, &B);
|
||||||
|
ge25519_unpack_negative_vartime(&B, base_pk);
|
||||||
|
|
||||||
|
bignum256modm ALIGN(16) a;
|
||||||
|
expand256_modm(a, &secret[SKPREFIX_SIZE], 32);
|
||||||
|
ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a);
|
||||||
|
ge25519_add(&A, &A, &B);
|
||||||
|
ge25519_pack(pk, &A);
|
||||||
|
|
||||||
|
printf("pk from public: ");
|
||||||
|
for (size_t i = 0; i < sizeof(pk); i++)
|
||||||
|
printf("%02x ", pk[i]);
|
||||||
|
puts("");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
hash_512bits base_extsk;
|
||||||
|
bignum256modm ALIGN(16) a, b;
|
||||||
|
ge25519 ALIGN(16) A;
|
||||||
|
u8 pk[32];
|
||||||
|
|
||||||
|
expand256_modm(a, &secret[32], 32);
|
||||||
|
ed25519_seckey_expand(base_extsk, base_sk);
|
||||||
|
expand256_modm(b, base_extsk, 32);
|
||||||
|
|
||||||
|
add256_modm(a, a, b);
|
||||||
|
|
||||||
|
ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a);
|
||||||
|
ge25519_pack(pk, &A);
|
||||||
|
|
||||||
|
contract256_modm(&secret[32], a);
|
||||||
|
|
||||||
|
expand256_modm(a, &secret[32], 32);
|
||||||
|
ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a);
|
||||||
|
ge25519_pack(pk, &A);
|
||||||
|
|
||||||
|
printf("new pk: ");
|
||||||
|
for (size_t i = 0; i < sizeof(pk); i++)
|
||||||
|
printf("%02x ", pk[i]);
|
||||||
|
puts("");
|
||||||
|
|
||||||
|
char *newname = malloc(strlen(hs_secretkey) + strlen(".fixed") + 1);
|
||||||
|
strcpy(newname, hs_secretkey);
|
||||||
|
strcat(newname, ".fixed");
|
||||||
|
printf("saving to %s\n", newname);
|
||||||
|
|
||||||
|
fp = fopen(newname, "w");
|
||||||
|
if (!fp) {
|
||||||
|
perror("couldn't open");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (fwrite(secret, 1, sizeof secret, fp) != sizeof secret) {
|
||||||
|
perror("failed to write fixed privkey");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
#include "ed25519/ed25519_impl_post.h"
|
||||||
|
|
||||||
int main(int argc,char **argv)
|
int main(int argc,char **argv)
|
||||||
{
|
{
|
||||||
const char *outfile = 0;
|
const char *outfile = 0;
|
||||||
const char *infile = 0;
|
const char *infile = 0;
|
||||||
const char *onehostname = 0;
|
const char *onehostname = 0;
|
||||||
|
const char *basekeyfile = 0;
|
||||||
const char *arg;
|
const char *arg;
|
||||||
int ignoreargs = 0;
|
int ignoreargs = 0;
|
||||||
int dirnameflag = 0;
|
int dirnameflag = 0;
|
||||||
|
@ -326,6 +482,28 @@ int main(int argc,char **argv)
|
||||||
printversion();
|
printversion();
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(arg,"combine")) {
|
||||||
|
if (argc != 2) {
|
||||||
|
printhelp(stdout,progname);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
combine(argv[0],argv[1]);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
else if (!strcmp(arg,"genbase")) {
|
||||||
|
if (argc != 2) {
|
||||||
|
printhelp(stdout,progname);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
genbase(argv[0],argv[1]);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
else if (!strcmp(arg,"basekey")) {
|
||||||
|
if (argc--)
|
||||||
|
basekeyfile = *argv++;
|
||||||
|
else
|
||||||
|
e_additional();
|
||||||
|
}
|
||||||
else if (!strcmp(arg,"rawyaml"))
|
else if (!strcmp(arg,"rawyaml"))
|
||||||
yamlraw = 1;
|
yamlraw = 1;
|
||||||
#ifdef PASSPHRASE
|
#ifdef PASSPHRASE
|
||||||
|
@ -497,6 +675,28 @@ int main(int argc,char **argv)
|
||||||
filters_add(arg);
|
filters_add(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wt != WT_SLOW) {
|
||||||
|
fprintf(stderr,"you're not using -Z. this will probably break.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (basekeyfile) {
|
||||||
|
u8 base_pk[32];
|
||||||
|
FILE *fp = fopen(basekeyfile, "r");
|
||||||
|
if (!fp) {
|
||||||
|
perror("couldn't open basekey");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (fread(base_pk, 1, sizeof base_pk, fp) != sizeof base_pk) {
|
||||||
|
perror("incomplete read of base_pk");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
ed25519_pubkey_setbase(base_pk);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "This build requires using --basekey.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
if (yamlinput && yamloutput) {
|
if (yamlinput && yamloutput) {
|
||||||
fprintf(stderr,"both -y and -Y does not make sense\n");
|
fprintf(stderr,"both -y and -Y does not make sense\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
59
worker.c
59
worker.c
|
@ -60,6 +60,9 @@ pthread_mutex_t determseed_mutex;
|
||||||
u8 determseed[SEED_LEN];
|
u8 determseed[SEED_LEN];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int ed25519_pubkey_onbase(u8 *pk,const u8 *sk);
|
||||||
|
static void sanitycheck(const u8 *sk, const u8 *pk);
|
||||||
|
|
||||||
|
|
||||||
char *makesname(void)
|
char *makesname(void)
|
||||||
{
|
{
|
||||||
|
@ -88,16 +91,7 @@ static void onionready(char *sname,const u8 *secret,const u8 *pubonion)
|
||||||
pthread_mutex_unlock(&keysgenerated_mutex);
|
pthread_mutex_unlock(&keysgenerated_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// disabled as this was never ever triggered as far as I'm aware
|
sanitycheck(&secret[SKPREFIX_SIZE], &pubonion[PKPREFIX_SIZE]);
|
||||||
#if 0
|
|
||||||
// Sanity check that the public key matches the private one.
|
|
||||||
ge_p3 ALIGN(16) point;
|
|
||||||
u8 testpk[PUBLIC_LEN];
|
|
||||||
ge_scalarmult_base(&point,&secret[SKPREFIX_SIZE]);
|
|
||||||
ge_p3_tobytes(testpk,&point);
|
|
||||||
if (memcmp(testpk,&pubonion[PKPREFIX_SIZE],PUBLIC_LEN) != 0)
|
|
||||||
abort();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!yamloutput) {
|
if (!yamloutput) {
|
||||||
if (createdir(sname,1) != 0) {
|
if (createdir(sname,1) != 0) {
|
||||||
|
@ -266,3 +260,48 @@ void worker_init(void)
|
||||||
crypto_sign_ed25519_donna_ge_initeightpoint();
|
crypto_sign_ed25519_donna_ge_initeightpoint();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// there's not really any good place to add ed25519 functions
|
||||||
|
// so i just add them there
|
||||||
|
// i don't understand how this codebase is organized :(
|
||||||
|
|
||||||
|
ge25519 ALIGN(16) PUBKEY_BASE = {0};
|
||||||
|
int pubkey_base_initialized;
|
||||||
|
|
||||||
|
void ed25519_pubkey_setbase(const u8 base_pk[32])
|
||||||
|
{
|
||||||
|
u8 tmp_pk[32];
|
||||||
|
ge25519_unpack_negative_vartime(&PUBKEY_BASE, base_pk);
|
||||||
|
// dumb hack: unpack flips the point. to get the original point
|
||||||
|
// back, i just pack and unpack it again
|
||||||
|
ge25519_pack(tmp_pk, &PUBKEY_BASE);
|
||||||
|
ge25519_unpack_negative_vartime(&PUBKEY_BASE, tmp_pk);
|
||||||
|
pubkey_base_initialized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ed25519_pubkey_onbase(u8 *pk,const u8 *sk)
|
||||||
|
{
|
||||||
|
bignum256modm a;
|
||||||
|
ge25519 ALIGN(16) A;
|
||||||
|
|
||||||
|
if (unlikely(pubkey_base_initialized == 0))
|
||||||
|
abort();
|
||||||
|
|
||||||
|
// ge_scalarmult_base(&A, sk);
|
||||||
|
expand256_modm(a,sk,32);
|
||||||
|
ge25519_scalarmult_base_niels(&A,ge25519_niels_base_multiples,a);
|
||||||
|
ge25519_add(&A, &A, &PUBKEY_BASE);
|
||||||
|
ge25519_pack(pk,&A);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void sanitycheck(const u8 *sk, const u8 *pk) {
|
||||||
|
u8 testpk[PUBLIC_LEN];
|
||||||
|
ed25519_pubkey_onbase(testpk, sk);
|
||||||
|
if (memcmp(testpk,pk,PUBLIC_LEN) != 0) {
|
||||||
|
fprintf(stderr, "Sanity check failed. Either I fucked something up, or you're using an unsupported combination of options. Probably both.\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
1
worker.h
1
worker.h
|
@ -36,6 +36,7 @@ extern u8 determseed[SEED_LEN];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void worker_init(void);
|
extern void worker_init(void);
|
||||||
|
extern void ed25519_pubkey_setbase(const u8 base_pk[32]);
|
||||||
|
|
||||||
extern char *makesname(void);
|
extern char *makesname(void);
|
||||||
extern size_t worker_batch_memuse(void);
|
extern size_t worker_batch_memuse(void);
|
||||||
|
|
|
@ -42,7 +42,7 @@ again:
|
||||||
if (unlikely(endwork))
|
if (unlikely(endwork))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
ed25519_pubkey(pk,sk);
|
ed25519_pubkey_onbase(pk,sk);
|
||||||
|
|
||||||
#ifdef STATISTICS
|
#ifdef STATISTICS
|
||||||
++st->numcalc.v;
|
++st->numcalc.v;
|
||||||
|
|
Loading…
Add table
Reference in a new issue