Obtenga la clave pública de la firma en un contrato inteligente (nota, clave pública, no dirección)

¿Hay bibliotecas para obtener una clave pública de una firma en un contrato inteligente? El método ecrecover devuelve una dirección, no una clave pública, y para realizar cálculos que necesitan derivar una clave pública de una firma, donde la clave pública no se conoce y no se transfiere al contrato por otros medios, mientras que la firma es conocida. sería bueno tener una biblioteca que obtenga la clave pública de una firma.

Las bibliotecas parciales también serían útiles aquí.

Respuestas (3)

Hay una biblioteca https://github.com/jbaylina/ecsol que implementa algunas operaciones sobre curvas elípticas en solidez.

No lo intenté, pero parece tener suficiente para implementar la recuperación de clave pública. Pero no estoy seguro de si el límite de gas permitirá tal operación.

En cualquier caso el problema parece interesante, pero equivale a obtener una preimagen de keccak.

No hay una forma integrada de hacer esto en Solidity y tampoco creo que exista una biblioteca para hacerlo. Por curiosidad, ¿cuál es la razón por la que necesita obtener la clave pública en lugar de la dirección?

una tercera versión de esta recompensa, etherscan.io/address/… donde se pasa una clave simétrica al contrato en lugar de una clave pública, y la clave pública (utilizada para resolver otro cifrado) se deriva de una firma de un identificador de cuenta
un esquema de firma que utiliza claves de un solo uso, llamándolo "teikhos", del griego "fortificación", oculta la criptografía asimétrica detrás de un cifrado simétrico indescifrable (solo se puede romper por fuerza bruta en todas las combinaciones posibles)

una nueva biblioteca está disponible para recuperar la clave pública del mensaje firmado ECDSA https://github.com/0xcyphered/secp256k1-solidity

Ejemplo:

//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;
import "@0xcyphered/secp256k1-solidity/contracts/SECP256K1.sol";
contract Example {
    function recoverPersonalSignPublicKey(
        bytes32 message,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public pure returns (bytes memory) {
        string memory header = '\x19Ethereum Signed Message:\n32';
        bytes32 _message = keccak256(abi.encodePacked(header, message));
        (uint256 x, uint256 y) = SECP256K1.recover(uint256(_message), v - 27, uint256(r), uint256(s));
        return abi.encodePacked(x, y);
    }
}