87 lines
2.6 KiB
C
87 lines
2.6 KiB
C
#ifdef HAVE_ETH2
|
|
|
|
#include "shared_context.h"
|
|
#include "apdu_constants.h"
|
|
|
|
#include "feature_getEth2PublicKey.h"
|
|
#include "common_ui.h"
|
|
#include "os_io_seproxyhal.h"
|
|
|
|
static const uint8_t BLS12_381_FIELD_MODULUS[] = {
|
|
0x1a, 0x01, 0x11, 0xea, 0x39, 0x7f, 0xe6, 0x9a, 0x4b, 0x1b, 0xa7, 0xb6, 0x43, 0x4b, 0xac, 0xd7,
|
|
0x64, 0x77, 0x4b, 0x84, 0xf3, 0x85, 0x12, 0xbf, 0x67, 0x30, 0xd2, 0xa0, 0xf6, 0xb0, 0xf6, 0x24,
|
|
0x1e, 0xab, 0xff, 0xfe, 0xb1, 0x53, 0xff, 0xff, 0xb9, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xab};
|
|
|
|
void getEth2PublicKey(uint32_t *bip32Path, uint8_t bip32PathLength, uint8_t *out) {
|
|
uint8_t privateKeyData[INT256_LENGTH];
|
|
cx_ecfp_256_extended_private_key_t privateKey;
|
|
cx_ecfp_384_public_key_t publicKey;
|
|
uint8_t yFlag = 0;
|
|
uint8_t tmp[96];
|
|
|
|
io_seproxyhal_io_heartbeat();
|
|
os_perso_derive_eip2333(CX_CURVE_BLS12_381_G1, bip32Path, bip32PathLength, privateKeyData);
|
|
io_seproxyhal_io_heartbeat();
|
|
memset(tmp, 0, 48);
|
|
memmove(tmp + 16, privateKeyData, 32);
|
|
cx_ecfp_init_private_key(CX_CURVE_BLS12_381_G1, tmp, 48, (cx_ecfp_private_key_t *) &privateKey);
|
|
cx_ecfp_generate_pair(CX_CURVE_BLS12_381_G1,
|
|
(cx_ecfp_public_key_t *) &publicKey,
|
|
(cx_ecfp_private_key_t *) &privateKey,
|
|
1);
|
|
explicit_bzero(tmp, 96);
|
|
explicit_bzero((void *) &privateKey, sizeof(cx_ecfp_256_extended_private_key_t));
|
|
tmp[47] = 2;
|
|
cx_math_mult(tmp, publicKey.W + 1 + 48, tmp, 48);
|
|
if (cx_math_cmp(tmp + 48, BLS12_381_FIELD_MODULUS, 48) > 0) {
|
|
yFlag = 0x20;
|
|
}
|
|
publicKey.W[1] &= 0x1f;
|
|
publicKey.W[1] |= 0x80 | yFlag;
|
|
memmove(out, publicKey.W + 1, 48);
|
|
}
|
|
|
|
void handleGetEth2PublicKey(uint8_t p1,
|
|
uint8_t p2,
|
|
const uint8_t *dataBuffer,
|
|
uint16_t dataLength,
|
|
unsigned int *flags,
|
|
unsigned int *tx) {
|
|
bip32_path_t bip32;
|
|
|
|
if (!called_from_swap) {
|
|
reset_app_context();
|
|
}
|
|
if ((p1 != P1_CONFIRM) && (p1 != P1_NON_CONFIRM)) {
|
|
THROW(0x6B00);
|
|
}
|
|
if (p2 != 0) {
|
|
THROW(0x6B00);
|
|
}
|
|
|
|
dataBuffer = parseBip32(dataBuffer, &dataLength, &bip32);
|
|
|
|
if (dataBuffer == NULL) {
|
|
THROW(0x6a80);
|
|
}
|
|
|
|
getEth2PublicKey(bip32.path, bip32.length, tmpCtx.publicKeyContext.publicKey.W);
|
|
|
|
#ifndef NO_CONSENT
|
|
if (p1 == P1_NON_CONFIRM)
|
|
#endif // NO_CONSENT
|
|
{
|
|
*tx = set_result_get_eth2_publicKey();
|
|
THROW(0x9000);
|
|
}
|
|
#ifndef NO_CONSENT
|
|
else {
|
|
ui_display_public_eth2();
|
|
|
|
*flags |= IO_ASYNCH_REPLY;
|
|
}
|
|
#endif // NO_CONSENT
|
|
}
|
|
|
|
#endif
|