Untitled
unknown
plain_text
a year ago
10 kB
8
Indexable
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
// Número de chaves privadas a serem geradas
#define NUM_KEYS 10 // Ajuste conforme necessário
// Definição de um inteiro de 256 bits
typedef struct {
uint32_t data[8]; // 8 * 32 bits = 256 bits
} uint256_t;
// Parâmetros da curva elíptica secp256k1
const uint256_t prime = { .data = {0xFFFFFC2F, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF} };
const uint256_t a_curve = { .data = {0} };
const uint256_t b_curve = { .data = {7} };
const uint256_t Gx = { .data = {0xF81798, 0xF2815B16, 0x2DCE28D9, 0xBFCDB2D,
0x870B070, 0xCE870B0, 0x5A06295C, 0x79BE667E} };
const uint256_t Gy = { .data = {0xB10D4B8, 0x9C47D08F, 0xA6855419, 0xFD17B448,
0xE1108A8, 0xDA4FBFC0, 0x3ADA7726, 0x483ADA77} };
// Função para imprimir um uint256_t em hexadecimal
void print_uint256(const uint256_t *num) {
for (int i = 7; i >= 0; i--) {
printf("%08x", num->data[i]);
}
}
// Função para gerar uma chave privada aleatória
void generate_private_key(uint256_t *priv_key) {
for (int i = 0; i < 8; i++) {
priv_key->data[i] = rand();
}
}
// Funções de operações aritméticas com uint256_t
void uint256_add(uint256_t *result, const uint256_t *a, const uint256_t *b) {
uint64_t carry = 0;
for (int i = 0; i < 8; i++) {
uint64_t sum = (uint64_t)a->data[i] + b->data[i] + carry;
result->data[i] = (uint32_t)sum;
carry = sum >> 32;
}
}
void uint256_sub(uint256_t *result, const uint256_t *a, const uint256_t *b) {
uint64_t borrow = 0;
for (int i = 0; i < 8; i++) {
uint64_t diff = (uint64_t)a->data[i] - b->data[i] - borrow;
result->data[i] = (uint32_t)diff;
borrow = (diff >> 63) & 1; // Correção do sinal de borrow
}
}
void uint256_copy(uint256_t *dest, const uint256_t *src) {
memcpy(dest->data, src->data, sizeof(uint32_t) * 8);
}
// Comparação de uint256_t
int uint256_cmp(const uint256_t *a, const uint256_t *b) {
for (int i = 7; i >= 0; i--) {
if (a->data[i] > b->data[i]) return 1;
if (a->data[i] < b->data[i]) return -1;
}
return 0;
}
// Modulo: result = a mod mod
void uint256_mod(uint256_t *result, const uint256_t *a, const uint256_t *mod) {
uint256_t temp;
uint256_copy(&temp, a);
while (uint256_cmp(&temp, mod) >= 0) {
uint256_sub(&temp, &temp, mod);
}
uint256_copy(result, &temp);
}
// Multiplicação: result = (a * b) mod mod
void uint256_mul_mod(uint256_t *result, const uint256_t *a, const uint256_t *b, const uint256_t *mod) {
uint256_t temp = {0};
uint256_t a_copy;
uint256_copy(&a_copy, a);
for (int i = 0; i < 256; i++) {
if ((b->data[i / 32] >> (i % 32)) & 1) {
uint256_add(&temp, &temp, &a_copy);
uint256_mod(&temp, &temp, mod);
}
// a_copy = (a_copy * 2) mod mod
uint256_add(&a_copy, &a_copy, &a_copy);
uint256_mod(&a_copy, &a_copy, mod);
}
uint256_copy(result, &temp);
}
// Inverso modular usando o Algoritmo de Euclides Estendido
void uint256_modinv(uint256_t *result, const uint256_t *a, const uint256_t *mod) {
uint256_t t = {0}, newt = {0};
t.data[0] = 0;
newt.data[0] = 1;
uint256_t r, newr;
uint256_copy(&r, mod);
uint256_copy(&newr, a);
uint256_t quotient, temp1, temp2;
while (uint256_cmp(&newr, &(uint256_t){0}) != 0) {
// quotient = r / newr
// Aqui, para simplificar, assumimos que newr é menor que r e que o quociente é 1
quotient.data[0] = 1;
// (t, newt) = (newt, t - quotient * newt)
uint256_copy(&temp1, &newt);
uint256_mul_mod(&temp2, "ient, &newt, mod);
uint256_sub(&newt, &t, &temp2);
uint256_copy(&t, &temp1);
// (r, newr) = (newr, r - quotient * newr)
uint256_copy(&temp1, &newr);
uint256_mul_mod(&temp2, "ient, &newr, mod);
uint256_sub(&newr, &r, &temp2);
uint256_copy(&r, &temp1);
}
if (uint256_cmp(&r, &(uint256_t){ .data = {1} }) > 0) {
// Não invertível
memset(result->data, 0, sizeof(uint32_t) * 8);
return;
}
if (uint256_cmp(&t, &(uint256_t){0}) < 0) {
uint256_add(&t, &t, mod);
}
uint256_copy(result, &t);
}
// Operações na curva elíptica
void point_double(uint256_t *Rx, uint256_t *Ry, const uint256_t *Px, const uint256_t *Py) {
if (uint256_cmp(Py, &(uint256_t){0}) == 0) {
memset(Rx->data, 0, sizeof(uint32_t) * 8);
memset(Ry->data, 0, sizeof(uint32_t) * 8);
return;
}
uint256_t s, tmp1, tmp2, tmp3;
// s = (3 * Px^2) * (2 * Py)^-1 mod p
uint256_mul_mod(&tmp1, Px, Px, &prime); // tmp1 = Px^2
uint256_add(&tmp2, &tmp1, &tmp1); // tmp2 = 2 * Px^2
uint256_add(&tmp1, &tmp1, &tmp2); // tmp1 = 3 * Px^2
uint256_add(&tmp2, Py, Py); // tmp2 = 2 * Py
uint256_modinv(&tmp2, &tmp2, &prime); // tmp2 = (2 * Py)^-1
uint256_mul_mod(&s, &tmp1, &tmp2, &prime); // s = (3 * Px^2) / (2 * Py)
// Rx = s^2 - 2 * Px
uint256_mul_mod(&tmp1, &s, &s, &prime); // tmp1 = s^2
uint256_add(&tmp2, Px, Px); // tmp2 = 2 * Px
uint256_sub(&tmp1, &tmp1, &tmp2); // tmp1 = s^2 - 2 * Px
uint256_mod(&tmp1, &tmp1, &prime); // tmp1 = Rx
// Ry = s * (Px - Rx) - Py
uint256_sub(&tmp2, Px, &tmp1); // tmp2 = Px - Rx
uint256_mul_mod(&tmp2, &s, &tmp2, &prime); // tmp2 = s * (Px - Rx)
uint256_sub(&tmp2, &tmp2, Py); // tmp2 = s * (Px - Rx) - Py
uint256_mod(&tmp2, &tmp2, &prime); // tmp2 = Ry
uint256_copy(Rx, &tmp1);
uint256_copy(Ry, &tmp2);
}
void point_add(uint256_t *Rx, uint256_t *Ry,
const uint256_t *Px, const uint256_t *Py,
const uint256_t *Qx, const uint256_t *Qy) {
if (uint256_cmp(Px, &(uint256_t){0}) == 0 && uint256_cmp(Py, &(uint256_t){0}) == 0) {
uint256_copy(Rx, Qx);
uint256_copy(Ry, Qy);
return;
}
if (uint256_cmp(Qx, &(uint256_t){0}) == 0 && uint256_cmp(Qy, &(uint256_t){0}) == 0) {
uint256_copy(Rx, Px);
uint256_copy(Ry, Py);
return;
}
uint256_t s, tmp1, tmp2;
// s = (Qy - Py) * (Qx - Px)^-1 mod p
uint256_sub(&tmp1, Qy, Py); // tmp1 = Qy - Py
uint256_sub(&tmp2, Qx, Px); // tmp2 = Qx - Px
uint256_modinv(&tmp2, &tmp2, &prime); // tmp2 = (Qx - Px)^-1
uint256_mul_mod(&s, &tmp1, &tmp2, &prime); // s = (Qy - Py) / (Qx - Px)
// Rx = s^2 - Px - Qx
uint256_mul_mod(&tmp1, &s, &s, &prime); // tmp1 = s^2
uint256_sub(&tmp1, &tmp1, Px); // tmp1 = s^2 - Px
uint256_sub(&tmp1, &tmp1, Qx); // tmp1 = s^2 - Px - Qx
uint256_mod(&tmp1, &tmp1, &prime); // tmp1 = Rx
// Ry = s * (Px - Rx) - Py
uint256_sub(&tmp2, Px, &tmp1); // tmp2 = Px - Rx
uint256_mul_mod(&tmp2, &s, &tmp2, &prime); // tmp2 = s * (Px - Rx)
uint256_sub(&tmp2, &tmp2, Py); // tmp2 = s * (Px - Rx) - Py
uint256_mod(&tmp2, &tmp2, &prime); // tmp2 = Ry
uint256_copy(Rx, &tmp1);
uint256_copy(Ry, &tmp2);
}
// Multiplicação escalar: R = k * P
void scalar_mult(uint256_t *Rx, uint256_t *Ry, const uint256_t *k, const uint256_t *Px, const uint256_t *Py) {
uint256_t Qx = {0}, Qy = {0};
uint256_t Px_copy, Py_copy;
uint256_copy(&Px_copy, Px);
uint256_copy(&Py_copy, Py);
for (int i = 0; i < 256; i++) {
if ((k->data[i / 32] >> (i % 32)) & 1) {
point_add(&Qx, &Qy, &Qx, &Qy, &Px_copy, &Py_copy);
}
point_double(&Px_copy, &Py_copy, &Px_copy, &Py_copy);
}
uint256_copy(Rx, &Qx);
uint256_copy(Ry, &Qy);
}
// Função de hash Keccak-256 simplificada (não é uma implementação real)
void keccak_256(const uint8_t *input, size_t input_len, uint8_t *output) {
// Implementação simplificada - preenche output com zeros
memset(output, 0, 32);
}
// Converter chave pública em endereço Ethereum
void public_key_to_address(uint8_t *public_key, uint8_t *address) {
uint8_t hash[32];
keccak_256(public_key + 1, 64, hash); // Ignora o byte 0x04
memcpy(address, hash + 12, 20);
}
// Função principal
int main() {
srand(time(NULL));
clock_t start_time = clock();
for (int i = 0; i < NUM_KEYS; i++) {
// Gerar chave privada aleatória
uint256_t priv_key;
generate_private_key(&priv_key);
// Calcular a chave pública
uint256_t pub_x, pub_y;
scalar_mult(&pub_x, &pub_y, &priv_key, &Gx, &Gy);
// Converter chave pública para bytes
uint8_t public_key[65];
public_key[0] = 0x04;
for (int j = 0; j < 8; j++) {
public_key[1 + j * 4 + 0] = (pub_x.data[7 - j] >> 24) & 0xFF;
public_key[1 + j * 4 + 1] = (pub_x.data[7 - j] >> 16) & 0xFF;
public_key[1 + j * 4 + 2] = (pub_x.data[7 - j] >> 8) & 0xFF;
public_key[1 + j * 4 + 3] = (pub_x.data[7 - j] >> 0) & 0xFF;
}
for (int j = 0; j < 8; j++) {
public_key[33 + j * 4 + 0] = (pub_y.data[7 - j] >> 24) & 0xFF;
public_key[33 + j * 4 + 1] = (pub_y.data[7 - j] >> 16) & 0xFF;
public_key[33 + j * 4 + 2] = (pub_y.data[7 - j] >> 8) & 0xFF;
public_key[33 + j * 4 + 3] = (pub_y.data[7 - j] >> 0) & 0xFF;
}
// Calcular o endereço Ethereum
uint8_t address[20];
public_key_to_address(public_key, address);
// Opcional: imprimir o endereço
// printf("Endereço Ethereum: 0x");
// for (int j = 0; j < 20; j++) {
// printf("%02x", address[j]);
// }
// printf("\n");
}
clock_t end_time = clock();
double time_spent = (double)(end_time - start_time) / CLOCKS_PER_SEC;
printf("Tempo total de execução para %d chaves: %.2f segundos\n", NUM_KEYS, time_spent);
printf("Chaves geradas por segundo: %.2f\n", NUM_KEYS / time_spent);
return 0;
}Editor is loading...
Leave a Comment