What's your question? Anything specific?
That was just an example of range reduction via subtraction & division. As you can see, you can search in a smaller bit range but you have more public keys to look for.
It was the Bitcointalk forum that inspired us to create Bitcointalksearch.org - Bitcointalk is an excellent site that should be the default page for anybody dealing in cryptocurrency, since it is a virtual gold-mine of data. However, our experience and user feedback led us create our site; Bitcointalk's search is slow, and difficult to get the results you need, because you need to log in first to find anything useful - furthermore, there are rate limiters for their search functionality.
The aim of our project is to create a faster website that yields more results and faster without having to create an account and eliminate the need to log in - your personal data, therefore, will never be in jeopardy since we are not asking for any of your data and you don't need to provide them to use our site with all of its capabilities.
We created this website with the sole purpose of users being able to search quickly and efficiently in the field of cryptocurrency so they will have access to the latest and most accurate information and thereby assisting the crypto-community at large.
02f0c386f6714fe5940ec7e622d8ba2e5204c58cd71a9c73ca95fb0e4ec0e76d72
03f7f61f6fc40c3df9696ab839727b1dc1391a9da275ea6d42d17302cdccbdc09a
02c19b2db68679148bd96635d08fe824ba9bd20daab2873840aaabcfceec484a96
0209e65b3fe12c22728d87fcca8b984084b2f9b646fbabe2f5981024fb95eba4e1
038f479f61a73435ba2f038b1a54f1f54adb0508be58bd880b9174bea3aa7e86d5
039e894d63c7153c69f87868d9c63b02a8a011d942f4886d91bd5d8f58bb6b5afc
0381d7a33f05ade886db9bbcf96f8e1759fbffd2df33532753bab3433d281dc87f
02d25985c166a0ca3bf3f41e0d183df2f0a2cce1cf90caf79165b42cb12c1105db
032061e0311088d0d98131adf4a38b0bfbdcea1c23a732c3113169ddebb905a267
0242f66a0c1fa8c6b4ab00172b99e8bf92227570b2fb980e08f45a0db5bf617dd7
0239703514939aec42c3103e8a02c712b4f26903d559e92403ecd0511523ddedc9
0221a766fd4041d03ad65681684bde68db01dc9bdf09b3dcbb7fe513f71b81ae24
03d21e878ab0aeac492a88c1f5430e823a05201f50b2b6dda1af05e62c69d332ef
03642173b68ffd55b79ae59e8504e726285a5d916b8cf2224cf9dd3b6ab5550427
02124482f38119b78ced6d4cfdbb1f527538eea8158f7e7ca14507e70640e6f6ec
033df51c60c3e0cee9317eea3d97125a76aea5e9087a332df6fb47f5a7e78ac935
0249d150e04bf39f36c85499af2d56c285f93f647d563a8d644b03109a905d3ad8
03d999d94ebe5a16b8d473c4d00d325f0874926c8dea8a22aeb60b1a35f5543100
0380ede2c7f5cc251e1ecd52773e3dcebb3bc5fceab4ce89d62018b45ddc4ee3aa
024b97c8d72f48320211b5e67131799004be48250dce123c56e3fb89d68d9396e5
02a20ce9ba321bf7a13b45af5645a49eae0870dd0aee64ce48eec46904982e09f5
03248efe604a9bf36e86f2257d1af410565bab4ea237493c34b5b86a144a6470eb
02133205bad04b511da446fe2e4777d15b1aaaa7e99b084e67a2968daa7c1eb946
03d05d0862f0d677b838af72763982be68850d9b222081289dd191283e68c75058
02152bd00d55a9f82eef113d4e2b8c26e2c280b8c713154515fea807ff07e00fad
02f5f38191a6afbb8efda92c199626dc54362aeb4ec7df55adb0d3076af6251e71
03de0ae872279680997511720b05d197bd164955688bb27d1b8747a6b4b071322e
03ec224492baa0bfc9d3fe7388384aa74a0397d66acf9736434044981febfd4679
02ba62c3d3e7c6c782113d45d3426e222adefcef36f0241746340153dcc51c218c
02aec4e228a8bfea725af79be641788b0b7743b620cae1426d6f052bf4f1e451ed
022fdbce7c0ed6ff7f6461fad0b0361209db556c6668b63c62ec2d6ab5c1be53dc
03a16d65d082d8c4e655d20eac7b2d216b2e22ab2b6ed5133df4394669ec9d10a4
03858ecab60490237bf8053a7354223cdbfdc76634623800a8e64deb4aa0adc0c0
14zJF8CnG4hYZnPk4PYfc8gLU31Puqfgsv
1NRNqBzcGrhVPwcAG3mQtuVJk8LzbJbzJq
1JcJGT8ezp8EHsVDcDyPNa3Ar2zbhiy4ax
1HaCnLU7wssvrTUpEGDcBPebX4mmR21MWN
14Xuu5dGxwZpHf4mr1r4ziYDXdgMrFbDbP
19YPjv6E1642SPve4toMZkpo8TMvYvhin3
1Bdx4r4xx9UFRoVoR4QtgSjrcgEfpehia
1FJzTav9h59pi81yGXmgQAWu6ZergWEFZo
1GCzqPsWNN52M5oViktLdawZYMb912PXyZ
1GfWXSJ1eA14ap8enpUsVm2HTQV2cRBPZD
17e1To7mLCJzusa7sbs8habEzsMiF5jKej
1JPaPJpYUCsFn25ECZTZxU62mdrHTwYUkM
1JixzUPVmoeU25a84pUXf6xNfHBmoT8FXy
1EHUpUsHeLFNhLeivmkqZp4rYqivaq2Ghe
1CGAuzs7MRyXFpMnNTVsSvEknt2AxDPaLK
1JuaDBFmHFhV6ozKJbsnR9k3Mnv3PWB9GZ
1KRHnqXQyfLZuYVqPmfKSpZPNE4j2vCnRn
1JwHmAFSgrDsUV6ow9CvuYz4YKhiFHtdLm
1N7Vbc9bsYy6B4Qmf3Vr3wKjJJLf7xR4sk
1JkKmLkmuUg9g8UpzoJvrfz38bzYKKaA85
1GV5w1kvsybCiTk8EJ6JcwtioabaxPTF96
1M23DScXBhi1imqVqmTTvndrDQjACYpATp
1Kc3gPy54e68BsHVJreSqSHgm3fLeXnj2g
19PS9jCNYaQ4LnhJ3Yt8K9hcH6swBQi9pV
1CAxJ3uDxnAza79NfPbJXRoznYkA6w865Y
1DePnGTmKV8it1XQjXM9Y4cW7PhLQerFRY
14j7AZVuGMvTUavj1DRFE4Wp6dWGPrBeAc
165Echz8WdXjXdBZ8eAp6sUCPsWw8n62xg
1LEvqW3x8eF2jQeYLrjANAZWaFqvU3Xw7L
12AD1vSr1QcW2e2LZvMSHv63RXKT8eJUXo
15RTpbp2AfHp8d7Xgq8DbyNsT4rKDfxQCo
1BvJV9vp7Yg38rycEFtHxFYx9Aid2aD3RL
14UUWCMpLB6doUuTkUjsBAFXwpvCnADt9N
#include "field_impl.h" // field operations
#include "group_impl.h" // group operations
#define FE_INV(r, x) secp256k1_fe_impl_inv_var(&(r), &(x))
#define FE_MUL(r, a, b) secp256k1_fe_mul_inner((r).n, (a).n, (b).n)
#define FE_SQR(r, x) secp256k1_fe_sqr_inner((r).n, (x).n)
#define FE_ADD(r, d) secp256k1_fe_impl_add(&(r), &(d))
#define FE_NEG(r, a, m) secp256k1_fe_impl_negate_unchecked(&(r), &(a), (m))
static
void jump_batch(
secp256k1_ge * ge,
const secp256k1_ge * jp,
secp256k1_fe * xz, // product tree leafs + parent nodes
secp256k1_fe * xzOut,
U32 batch_size
) {
secp256k1_fe t1, t2, t3;
int64_t i;
for (i = 0; i < batch_size; i++) {
uint8_t jIdx;
#if JUMP_FUNC == JUMP_FUNC_LOW_52
jIdx = ge[i].x.n[0] % NUM_JUMP_POINTS;
#elif JUMP_FUNC == JUMP_FUNC_LOW_64
jIdx = (ge[i].x.n[0] | (ge[i].x.n[1] << 52)) % NUM_JUMP_POINTS;
#endif
xz[i] = ge[i].x;
FE_NEG(t1, jp[jIdx].x, 1);
FE_ADD(xz[i], t1); // XZ[i] = x1 - x2
}
for (i = 0; i < batch_size - 1; i++) {
FE_MUL(xz[batch_size + i], xz[i * 2], xz[i * 2 + 1]);
}
FE_INV(xzOut[batch_size * 2 - 2], xz[2 * batch_size - 2]);
for (i = batch_size - 2; i >= 0; i--) {
FE_MUL(xzOut[i * 2], xz[i * 2 + 1], xzOut[batch_size + i]);
FE_MUL(xzOut[i * 2 + 1], xz[i * 2], xzOut[batch_size + i]);
}
secp256k1_ge * _a = ge;
const secp256k1_fe * _inv = xzOut;
for (i = 0; i < batch_size; i++) {
uint8_t jIdx;
#if JUMP_FUNC == JUMP_FUNC_LOW_52
jIdx = ge[i].x.n[0] % NUM_JUMP_POINTS;
#elif JUMP_FUNC == JUMP_FUNC_LOW_64
jIdx = (ge[i].x.n[0] | (ge[i].x.n[1] << 52)) % NUM_JUMP_POINTS;
#endif
const secp256k1_ge * _b = &jp[jIdx];
FE_NEG(t1, _b->y, 1); // T1 = -y2
FE_ADD(_a->y, t1); // Y1 = y1 - y2 m = max_y + 2(1)
FE_MUL(_a->y, _a->y, *_inv); // Y1 = m = (y1 - y2) / (x1 - x2) m = 1
FE_SQR(t2, _a->y); // T2 = m**2 m = 1
FE_NEG(t3, _b->x, 1); // T3 = -x2
FE_ADD(t2, t3); // T2 = m**2 - x2 m = 1 + 2(1) = 3(2)
FE_NEG(_a->x, _a->x, 1); // X1 = -x1 m = max_x + 1
FE_ADD(_a->x, t2); // X1 = x3 = m**2 - x1 - x2 max_x = 3 + max_x + 1
secp256k1_fe_normalize_weak(&_a->x);
FE_NEG(t2, _a->x, 1); // T2 = -x3 m = 1 + 1 = 2
FE_ADD(t2, _b->x); // T1 = x2 - x3 m = 2 + 1 = 3
FE_MUL(_a->y, _a->y, t2); // Y1 = m * (x2 - x3) m = 1
FE_ADD(_a->y, t1); // Y1 = y3 = m * (x2 - x3) - y2 m = 1 + 2 = 3
secp256k1_fe_normalize_weak(&_a->y);
++_a;
++_inv;
}
}
static
void computeBatchJump(
secp256k1_ge * ge,
const secp256k1_ge * jp,
U32 batch_size,
U32 num_jumps
) {
size_t tree_sz = (batch_size * 2 - 1) * sizeof(secp256k1_fe);
// printf("Allocating %zu bytes for tree\n", tree_sz);
secp256k1_fe * xz_1 = malloc(tree_sz);
if (NULL == xz_1) return;
secp256k1_fe * xz_2 = malloc(tree_sz);
if (NULL == xz_2) return;
for (uint32_t loop = 0; loop < num_jumps; loop++) {
jump_batch(ge, jp, xz_1, xz_2, batch_size);
}
free(xz_1);
free(xz_2);
}
#define JUMPS_PER_STAGE 32768
secp256k1_ge * secp_ge = malloc(numElements * sizeof(secp256k1_ge));
secp256k1_ge * secp_jp = malloc(NUM_JUMP_POINTS * sizeof(secp256k1_ge));
// init the jump points, init the kangaroos to your needs
// ...
int numLaunches = 1; // extra multiplier for the total number of jumps
int numThr = omp_get_max_threads();
// use the max amount of threads that exactly divides the number of items
while (numThr > 0 && numElements % numThr) numThr--;
U64 gePerPart = numElements / numThr;
printf("\tThreads: %u; elements/thread: %lu\n", numThr, gePerPart);
double ompStartTime = omp_get_wtime();
for (U32 launchIdx = 0; launchIdx < numLaunches; launchIdx++) {
#pragma omp parallel for
for (U32 tIdx = 0; tIdx < numThr; tIdx++) {
U64 offset = tIdx * gePerPart;
secp256k1_ge * localGE = secp_ge + offset;
computeBatchJump(localGE, secp_jp, gePerPart, JUMPS_PER_STAGE);
}
}
double ompEndTime = omp_get_wtime();
elapsedTime = ompEndTime - ompStartTime;
speed = (double) totalCount / elapsedTime;