Untitled
unknown
plain_text
6 months ago
10 kB
6
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