2 void *worker_batch(void *task
)
4 union pubonionunion pubonion
;
5 u8
* const pk
= &pubonion
.raw
[PKPREFIX_SIZE
];
6 u8 secret
[SKPREFIX_SIZE
+ SECRET_LEN
];
7 u8
* const sk
= &secret
[SKPREFIX_SIZE
];
9 u8 hashsrc
[checksumstrlen
+ PUBLIC_LEN
+ 1];
10 u8 wpk
[PUBLIC_LEN
+ 1];
14 // state to keep batch data
15 ge_p3 ge_batch
[BATCHNUM
];
16 fe
*(batchgez
)[BATCHNUM
];
17 fe tmp_batch
[BATCHNUM
];
18 bytes32 pk_batch
[BATCHNUM
];
24 struct statstruct
*st
= (struct statstruct
*)task
;
27 // set up right pointers
28 for (size_t b
= 0;b
< BATCHNUM
;++b
)
29 batchgez
[b
] = &GEZ(ge_batch
[b
]);
33 memcpy(secret
,skprefix
,SKPREFIX_SIZE
);
35 memset(&pubonion
,0,sizeof(pubonion
));
36 memcpy(pubonion
.raw
,pkprefix
,PKPREFIX_SIZE
);
37 // write version later as it will be overwritten by hash
38 memcpy(hashsrc
,checksumstr
,checksumstrlen
);
39 hashsrc
[checksumstrlen
+ PUBLIC_LEN
] = 0x03; // version
48 randombytes(seed
,sizeof(seed
));
50 ed25519_seckey_expand(sk
,seed
);
52 ge_scalarmult_base(&ge_public
,sk
);
54 for (counter
= 0;counter
< SIZE_MAX
-(8*BATCHNUM
);counter
+= 8*BATCHNUM
) {
57 if (unlikely(endwork
))
61 for (size_t b
= 0;b
< BATCHNUM
;++b
) {
62 ge_batch
[b
] = ge_public
;
63 ge_add(&sum
,&ge_public
,&ge_eightpoint
);
64 ge_p1p1_to_p3(&ge_public
,&sum
);
66 // NOTE: leaves unfinished one bit at the very end
67 ge_p3_batchtobytes_destructive_1(pk_batch
,ge_batch
,batchgez
,tmp_batch
,BATCHNUM
);
70 st
->numcalc
.v
+= BATCHNUM
;
73 for (size_t b
= 0;b
< BATCHNUM
;++b
) {
74 DOFILTER(i
,pk_batch
[b
],{
76 shiftpk(wpk
,pk_batch
[b
],filter_len(i
));
79 DOFILTER(j
,wpk
,goto secondfind
);
84 shiftpk(wpk
,wpk
,filter_len(j
));
89 ge_p3_batchtobytes_destructive_finish(pk_batch
[b
],&ge_batch
[b
]);
91 memcpy(pk
,pk_batch
[b
],PUBLIC_LEN
);
92 // update secret key with counter
93 addsztoscalar32(sk
,counter
+ (b
* 8));
95 if ((sk
[0] & 248) != sk
[0] || ((sk
[31] & 63) | 64) != sk
[31])
101 memcpy(&hashsrc
[checksumstrlen
],pk
,PUBLIC_LEN
);
102 FIPS202_SHA3_256(hashsrc
,sizeof(hashsrc
),&pk
[PUBLIC_LEN
]);
104 pk
[PUBLIC_LEN
+ 2] = 0x03;
106 strcpy(base32_to(&sname
[direndpos
],pk
,PUBONION_LEN
),".onion");
107 onionready(sname
,secret
,pubonion
.raw
);
108 pk
[PUBLIC_LEN
] = 0; // what is this for?
109 // don't reuse same seed
121 sodium_memzero(secret
,sizeof(secret
));
122 sodium_memzero(seed
,sizeof(seed
));