¿Cómo (sin bibliotecas) puedo obtener la dirección pública de una clave privada?

Quiero saber una forma de saber la dirección pública utilizada para la transferencia de fondos de la clave privada. (Como hace myetherwallet cuando obtiene la información de su billetera ingresando su clave privada)

No me importa con qué lenguaje de programación (incluso si prefiero javascript, si es posible).

Respuestas (2)

¿Estás seguro de que quieres escribir esto sin usar una biblioteca? Es prácticamente imposible hacer cosas criptográficas de forma segura, incluso con experiencia en criptografía.

Usted ha sido advertido. Pero para darle la menor cuerda posible para ahorcarse, todo lo que tiene que hacer es volver a implementar un par de funciones descritas en esta publicación de blog . Depende de usted averiguar qué tan lejos quiere llegar para eliminar las bibliotecas (¿escribir su propia biblioteca bignum? ¿Escribir su programa para que se ejecute en un ensamblaje baremetal para evitar el uso de bibliotecas de SO posiblemente comprometidas?) También puede ver el código utilizado para implementar la funcionalidad en una biblioteca. Todo lo que necesitas para Python es de código abierto .

Es principalmente para fines educativos. No lo implementaré en ningún lado excepto en un entorno de prueba.

Como dijo @lungj, realmente no es una buena idea no usar bibliotecas. Porque necesita usar criptografía de curva elíptica, que depende en gran medida de las propiedades matemáticas. También necesitarás sha3 para hash.

Si puede usar las bibliotecas elliptic para criptografía de curva elíptica y js-sha3 para hash sha3, aquí hay un breve ejemplo

const assert = require('assert');
const EC = require('elliptic').ec;
const keccak256 = require('js-sha3').keccak256;

async function main() {
  try {
    const ec = new EC('secp256k1');

    const key = ec.keyFromPrivate('208065a247edbe5df4d86fbdc0171303f23a76961be9f6013850dd2bdc759bbb', 'hex');

    const privateKey = key.getPrivate();
    const publicKey = key.getPublic().encode('hex').slice(2);
    assert.equal(publicKey, '836b35a026743e823a90a0ee3b91bf615c6a757e2b60b9e1dc1826fd0dd16106f7bc1e8179f665015f43c6c81f39062fc2086ed849625c06e04697698b21855e');

    const address = keccak256(Buffer.from(publicKey, 'hex')).slice(64 - 40);
    assert.equal(address, '0bed7abd61247635c1973eb38474a2516ed1d884');

    console.log(`Private Key: 0x${privateKey}`);
    console.log(`Public Key: 0x${publicKey}`);
    console.log(`Address: 0x${address.toString()}`);
  } catch (err) {
    console.log(err);
  }
}

main();

Debería salir

Clave privada: 0x14700869030423518308970518253936238282279417230371408086143856620903190600635

Clave pública: 0x836b35a026743e823a90a0ee3b91bf615c6a757e2b60b9e1dc1826fd0dd16106f7bc1e8179f665015f43c6c81f39062fc2086ed849625c06e04698598eb21

Dirección: 0x0bed7abd61247635c1973eb38474a2516ed1d884

Su bloque try-catch alrededor de main() no detectará ningún error, porque si main tiene un error, simplemente devolverá una promesa que rechaza. En lugar del bloque try-catch, deberías usar esto:main().catch(err => { console.error(err); });
Tienes razón, el try/catch debería estar dentro main().