Starkex v2 integration

This commit is contained in:
BTChip github
2020-11-24 00:11:55 +01:00
committed by TamtamHero
parent 61424e7907
commit 9854d12753
24 changed files with 1056 additions and 183 deletions

View File

@@ -6,14 +6,32 @@
void handleStarkwareProvideQuantum(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uint16_t dataLength, unsigned int *flags, unsigned int *tx) {
size_t i = 0;
uint8_t expectedDataSize = 20 + 32;
uint8_t addressZero = 0;
tokenDefinition_t *currentToken = NULL;
if (appState != APP_STATE_IDLE) {
reset_app_context();
}
if (dataLength != 20 + 32) {
switch(p1) {
case STARK_QUANTUM_LEGACY:
break;
case STARK_QUANTUM_ETH:
case STARK_QUANTUM_ERC20:
case STARK_QUANTUM_ERC721:
case STARK_QUANTUM_MINTABLE_ERC20:
case STARK_QUANTUM_MINTABLE_ERC721:
expectedDataSize += 32;
break;
default:
THROW(0x6B00);
}
if (dataLength != expectedDataSize) {
THROW(0x6700);
}
if (!allzeroes(dataBuffer, 20)) {
if (p1 == STARK_QUANTUM_LEGACY) {
addressZero = allzeroes(dataBuffer, 20);
}
if ((p1 != STARK_QUANTUM_ETH) && !addressZero) {
for(i=0; i<MAX_TOKEN; i++){
currentToken = &tmpCtx.transactionContext.tokens[i];
if (tmpCtx.transactionContext.tokenSet[i] && (os_memcmp(currentToken->address, dataBuffer, 20) == 0)) {
@@ -28,8 +46,12 @@ void handleStarkwareProvideQuantum(uint8_t p1, uint8_t p2, uint8_t *dataBuffer,
else {
i = MAX_TOKEN;
}
os_memmove(dataContext.tokenContext.quantum, dataBuffer + 20, 32);
memmove(dataContext.tokenContext.quantum, dataBuffer + 20, 32);
if (p1 != STARK_QUANTUM_LEGACY) {
memmove(dataContext.tokenContext.mintingBlob, dataBuffer + 20 + 32, 32);
}
dataContext.tokenContext.quantumIndex = i;
dataContext.tokenContext.quantumType = p1;
quantumSet = true;
THROW(0x9000);
}

View File

@@ -18,6 +18,10 @@ void handleStarkwareSignMessage(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uin
cx_ecfp_private_key_t privateKey;
poorstream_t bitstream;
bool selfTransfer = false;
uint8_t order = 1;
uint8_t protocol = 2;
uint8_t preOffset, postOffset;
uint8_t zeroTest;
// Initial checks
if (appState != APP_STATE_IDLE) {
reset_app_context();
@@ -29,18 +33,35 @@ void handleStarkwareSignMessage(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uin
}
switch(p1) {
case P1_STARK_ORDER:
if (dataLength != (20 + 32 + 20 + 32 + 4 + 4 + 8 + 8 + 4 + 4 + 1 + 4 * bip32PathLength)) {
THROW(0x6700);
}
protocol = 1;
break;
case P1_STARK_TRANSFER:
if (dataLength != (20 + 32 + 32 + 4 + 4 + 8 + 4 + 4 + 1 + 4 * bip32PathLength)) {
THROW(0x6700);
}
protocol = 1;
order = 0;
break;
case P1_STARK_ORDER_V2:
break;
case P1_STARK_TRANSFER_V2:
case P1_STARK_CONDITIONAL_TRANSFER:
order = 0;
break;
default:
THROW(0x6B00);
}
postOffset = (protocol == 2 ? 1 + 32 : 0);
preOffset = (protocol == 2 ? 1 : 0);
if (order) {
if (dataLength != (20 + 32 + 20 + 32 + 4 + 4 + 8 + 8 + 4 + 4 + 1 + 4 * bip32PathLength +
2 * postOffset)) {
THROW(0x6700);
}
}
else {
if (dataLength != (20 + 32 + 32 + 4 + 4 + 8 + 4 + 4 + 1 + 4 * bip32PathLength +
postOffset + (p1 == P1_STARK_CONDITIONAL_TRANSFER ? 32 + 20 : 0))) {
THROW(0x6700);
}
}
if (p2 != 0) {
THROW(0x6B00);
}
@@ -52,34 +73,62 @@ void handleStarkwareSignMessage(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uin
}
// Discard the path to use part of dataBuffer as a temporary buffer
os_memmove(dataBuffer, dataBuffer + offset, dataLength - offset);
// Fail immediately if the contract is unknown
if (!allzeroes(dataBuffer, 20) && getKnownToken(dataBuffer) == NULL) {
PRINTF("stark - cannot process unknown token %.*H", 20, dataBuffer);
dataContext.starkContext.conditional = (p1 == P1_STARK_CONDITIONAL_TRANSFER);
if (dataContext.starkContext.conditional) {
memmove(dataContext.starkContext.fact, dataBuffer + 20 + 32 + postOffset + 32 + 4 + 4 + 8 + 4 + 4, 32);
memmove(dataContext.starkContext.conditionAddress, dataBuffer + 20 + 32 + postOffset + 32 + 4 + 4 + 8 + 4 + 4 + 32, 20);
PRINTF("Fact %.*H\n", 32, dataContext.starkContext.fact);
PRINTF("Address %.*H\n", 20, dataContext.starkContext.conditionAddress);
}
zeroTest = allzeroes(dataBuffer + preOffset, 20);
if (zeroTest && (protocol == 2) && (dataBuffer[0] != STARK_QUANTUM_ETH)) {
PRINTF("stark - unexpected quantum descriptor type for null first address %d\n", dataBuffer[0]);
THROW(0x6A80);
}
if (!zeroTest && getKnownToken(dataBuffer + preOffset) == NULL) {
PRINTF("stark - cannot process unknown token %.*H", 20, dataBuffer + preOffset);
THROW(0x6A80);
}
if ((p1 == P1_STARK_ORDER) && (!allzeroes(dataBuffer + 20 + 32, 20) && getKnownToken(dataBuffer + 20 + 32) == NULL)) {
PRINTF("stark - cannot process unknown token %.*H", 20, dataBuffer + 20 + 32);
if (order) {
zeroTest = allzeroes(dataBuffer + 20 + 32 + postOffset + preOffset, 20);
if (zeroTest && (protocol == 2) && (dataBuffer[1 + 20 + 32 + 32] != STARK_QUANTUM_ETH)) {
PRINTF("stark - unexpected quantum descriptor type for null second address %d\n", dataBuffer[1 + 20 + 32 + 32]);
THROW(0x6A80);
}
if (!zeroTest && getKnownToken(dataBuffer + 20 + 32 + postOffset + preOffset) == NULL) {
PRINTF("stark - cannot process unknown token %.*H", 20, dataBuffer + 20 + 32 + postOffset + preOffset);
THROW(0x6A80);
}
}
// Prepare the Stark parameters
io_seproxyhal_io_heartbeat();
compute_token_id(&global_sha3, dataBuffer, dataBuffer + 20, dataContext.starkContext.w1);
if (p1 == P1_STARK_ORDER) {
io_seproxyhal_io_heartbeat();
compute_token_id(&global_sha3, dataBuffer + preOffset,
(protocol == 2 ? dataBuffer[0] : STARK_QUANTUM_LEGACY),
dataBuffer + preOffset + 20,
(protocol == 2 ? dataBuffer + 1 + 20 + 32 : NULL), false, dataContext.starkContext.w1);
if (order) {
io_seproxyhal_io_heartbeat();
compute_token_id(&global_sha3, dataBuffer + 20 + 32, dataBuffer + 20 + 32 + 20, dataContext.starkContext.w2);
offset = 20 + 32 + 20 + 32;
compute_token_id(&global_sha3, dataBuffer + 20 + 32 + postOffset + preOffset,
(protocol == 2 ? dataBuffer[1 + 20 + 32 + 32] : STARK_QUANTUM_LEGACY),
dataBuffer + 20 + 32 + postOffset + preOffset + 20,
(protocol == 2 ? dataBuffer + 1 + 20 + 32 + 32 + 1 + 20 + 32 : NULL), false, dataContext.starkContext.w2);
offset = 20 + 32 + postOffset + 20 + 32 + postOffset;
}
else {
os_memmove(dataContext.starkContext.w2, dataBuffer + 20 + 32, 32);
offset = 20 + 32 + 32;
else {
os_memmove(dataContext.starkContext.w2, dataBuffer + 20 + 32 + postOffset, 32);
offset = 20 + 32 + postOffset + 32;
}
poorstream_init(&bitstream, dataContext.starkContext.w3);
poorstream_write_bits(&bitstream, 0, 11); // padding
poorstream_write_bits(&bitstream, (p1 == P1_STARK_ORDER ? STARK_ORDER_TYPE : STARK_TRANSFER_TYPE), 4);
poorstream_write_bits(&bitstream,
(p1 == P1_STARK_CONDITIONAL_TRANSFER ? STARK_CONDITIONAL_TRANSFER_TYPE :
order ? STARK_ORDER_TYPE : STARK_TRANSFER_TYPE), 4);
poorstream_write_bits(&bitstream, U4BE(dataBuffer, offset), 31);
poorstream_write_bits(&bitstream, U4BE(dataBuffer, offset + 4), 31);
poorstream_write_bits(&bitstream, U8BE(dataBuffer, offset + 4 + 4), 63);
if (p1 == P1_STARK_ORDER) {
if (order) {
poorstream_write_bits(&bitstream, U8BE(dataBuffer, offset + 4 + 4 + 8), 63);
offset += 4 + 4 + 8 + 8;
}
@@ -93,16 +142,31 @@ void handleStarkwareSignMessage(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uin
PRINTF("stark w1 %.*H\n", 32, dataContext.starkContext.w1);
PRINTF("stark w2 %.*H\n", 32, dataContext.starkContext.w2);
PRINTF("stark w3 %.*H\n", 32, dataContext.starkContext.w3);
if (dataContext.starkContext.conditional) {
cx_keccak_init(&global_sha3, 256);
cx_hash((cx_hash_t*)&global_sha3, 0, dataContext.starkContext.conditionAddress, 20, NULL, 0);
cx_hash((cx_hash_t*)&global_sha3, CX_LAST, dataContext.starkContext.fact, 32, dataContext.starkContext.w4, 32);
dataContext.starkContext.w4[0] &= 0x03;
PRINTF("stark w4 %.*H\n", 32, dataContext.starkContext.w4);
}
// Prepare the UI
if (p1 == P1_STARK_ORDER) {
if (order) {
io_seproxyhal_io_heartbeat();
// amount to sell
stark_get_amount_string(dataBuffer, dataBuffer + 20, dataBuffer + 20 + 32 + 20 + 32 + 4 + 4, (char*)(dataBuffer + TMP_OFFSET), strings.common.fullAmount);
stark_get_amount_string(dataBuffer + preOffset,
dataBuffer + preOffset + 20,
dataBuffer + 20 + 32 + postOffset + 20 + 32 + postOffset + 4 + 4,
(char*)(dataBuffer + TMP_OFFSET), strings.common.fullAmount);
io_seproxyhal_io_heartbeat();
// amount to buy
stark_get_amount_string(dataBuffer + 20 + 32, dataBuffer + 20 + 32 + 20, dataBuffer + 20 + 32 + 20 + 32 + 4 + 4 + 8, (char*)(dataBuffer + TMP_OFFSET), strings.common.maxFee);
stark_get_amount_string(dataBuffer + 20 + 32 + postOffset + preOffset,
dataBuffer + 20 + 32 + postOffset + preOffset + 20,
dataBuffer + 20 + 32 + postOffset + 20 + 32 + postOffset + 4 + 4 + 8,
(char*)(dataBuffer + TMP_OFFSET), strings.common.maxFee);
// src vault ID
snprintf(strings.common.fullAddress, sizeof(strings.common.fullAddress), "%d", U4BE(dataBuffer, 20 + 32 + 20 + 32));
snprintf(strings.common.fullAddress, sizeof(strings.common.fullAddress), "%d",
U4BE(dataBuffer, 20 + 32 + postOffset + 20 + 32 + postOffset));
}
else {
cx_ecfp_public_key_t publicKey;
@@ -115,19 +179,34 @@ void handleStarkwareSignMessage(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uin
os_memset(&privateKey, 0, sizeof(privateKey));
os_memset(privateKeyData, 0, sizeof(privateKeyData));
io_seproxyhal_io_heartbeat();
selfTransfer = (os_memcmp(publicKey.W + 1, dataBuffer + 20 + 32, 32) == 0);
selfTransfer = (os_memcmp(publicKey.W + 1, dataBuffer + 20 + 32 + postOffset, 32) == 0);
PRINTF("self transfer %d\n", selfTransfer);
io_seproxyhal_io_heartbeat();
// amount to transfer
stark_get_amount_string(dataBuffer, dataBuffer + 20, dataBuffer + 20 + 32 + 32 + 4 + 4, (char*)(dataBuffer + TMP_OFFSET), tmpContent.tmp);
stark_get_amount_string(dataBuffer + preOffset,
dataBuffer + preOffset + 20,
dataBuffer + 20 + 32 + postOffset + 32 + 4 + 4, (char*)(dataBuffer + TMP_OFFSET), tmpContent.tmp);
// dest vault ID
snprintf(strings.tmp.tmp2, sizeof(strings.tmp.tmp2), "%d", U4BE(dataBuffer, 20 + 32 + 32 + 4));
snprintf(strings.tmp.tmp2, sizeof(strings.tmp.tmp2), "%d",
U4BE(dataBuffer, 20 + 32 + postOffset + 32 + 4));
if (!selfTransfer) {
snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "0x%.*H", 32, dataBuffer + 20 + 32);
memmove(dataContext.starkContext.transferDestination, dataBuffer + 20 + 32 + postOffset, 32);
snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "0x%.*H", 32, dataBuffer + 20 + 32 + postOffset);
}
}
if (order) {
ux_flow_init(0, ux_stark_limit_order_flow, NULL);
}
else {
if (selfTransfer) {
ux_flow_init(0, (dataContext.starkContext.conditional ? ux_stark_self_transfer_conditional_flow :
ux_stark_self_transfer_flow), NULL);
}
else {
ux_flow_init(0, (dataContext.starkContext.conditional ? ux_stark_transfer_conditional_flow :
ux_stark_transfer_flow), NULL);
}
}
ux_flow_init(0, p1 == P1_STARK_ORDER ? ux_stark_limit_order_flow : selfTransfer ?
ux_stark_self_transfer_flow : ux_stark_transfer_flow, NULL);
*flags |= IO_ASYNCH_REPLY;
}

View File

@@ -11,8 +11,10 @@ unsigned int io_seproxyhal_touch_stark_ok(const bagl_element_t *e) {
io_seproxyhal_io_heartbeat();
starkDerivePrivateKey(tmpCtx.transactionContext.bip32Path, tmpCtx.transactionContext.pathLength, privateKeyData);
io_seproxyhal_io_heartbeat();
stark_sign(signature, privateKeyData, dataContext.starkContext.w1, dataContext.starkContext.w2, dataContext.starkContext.w3);
G_io_apdu_buffer[0] = 0;
stark_sign(signature, privateKeyData, dataContext.starkContext.w1, dataContext.starkContext.w2,
dataContext.starkContext.w3,
(dataContext.starkContext.conditional ? dataContext.starkContext.w4 : NULL));
G_io_apdu_buffer[0] = 0;
format_signature_out(signature);
tx = 65;
G_io_apdu_buffer[tx++] = 0x90;

View File

@@ -5,6 +5,21 @@
unsigned int io_seproxyhal_touch_stark_ok(const bagl_element_t *e);
void stark_sign_display_master_account() {
snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "0x%.*H", 32, dataContext.starkContext.transferDestination);
}
void stark_sign_display_condition_address() {
strings.tmp.tmp[0] = '0';
strings.tmp.tmp[1] = 'x';
getEthAddressStringFromBinary(dataContext.starkContext.conditionAddress, (uint8_t*)(strings.tmp.tmp + 2), &global_sha3, chainConfig);
strings.tmp.tmp[42] = '\0';
}
void stark_sign_display_condition_fact() {
snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "0x%.*H", 32, dataContext.starkContext.fact);
}
UX_STEP_NOCB(ux_stark_limit_order_1_step,
pnn,
{
@@ -100,6 +115,19 @@ UX_STEP_NOCB(ux_stark_self_transfer_2_step,
.text = "Transfer"
});
UX_STEP_NOCB(ux_stark_conditional_transfer_2_step,
bnnn_paging,
{
.title = "Conditional",
.text = "Transfer"
});
UX_STEP_NOCB(ux_stark_self_conditional_transfer_2_step,
bnnn_paging,
{
.title = "Conditional",
.text = "Self Transfer"
});
UX_STEP_NOCB(ux_stark_transfer_3_step,
bnnn_paging,
@@ -140,6 +168,33 @@ UX_STEP_CB(
"Reject",
});
UX_STEP_NOCB_INIT(
ux_stark_conditional_transfer_4_step,
bnnn_paging,
stark_sign_display_master_account(),
{
.title = "Master Account",
.text = strings.tmp.tmp
});
UX_STEP_NOCB_INIT(
ux_stark_conditional_transfer_8_step,
bnnn_paging,
stark_sign_display_condition_address(),
{
.title = "Cond. Address",
.text = strings.tmp.tmp
});
UX_STEP_NOCB_INIT(
ux_stark_conditional_transfer_9_step,
bnnn_paging,
stark_sign_display_condition_fact(),
{
.title = "Cond. Fact",
.text = strings.tmp.tmp
});
UX_FLOW(ux_stark_transfer_flow,
&ux_stark_transfer_1_step,
&ux_stark_transfer_2_step,
@@ -159,4 +214,27 @@ UX_FLOW(ux_stark_self_transfer_flow,
&ux_stark_transfer_7_step
);
UX_FLOW(ux_stark_transfer_conditional_flow,
&ux_stark_transfer_1_step,
&ux_stark_conditional_transfer_2_step,
&ux_stark_transfer_3_step,
&ux_stark_conditional_transfer_4_step,
&ux_stark_transfer_5_step,
&ux_stark_conditional_transfer_8_step,
&ux_stark_conditional_transfer_9_step,
&ux_stark_transfer_6_step,
&ux_stark_transfer_7_step
);
UX_FLOW(ux_stark_self_transfer_conditional_flow,
&ux_stark_transfer_1_step,
&ux_stark_self_conditional_transfer_2_step,
&ux_stark_transfer_3_step,
&ux_stark_transfer_5_step,
&ux_stark_conditional_transfer_8_step,
&ux_stark_conditional_transfer_9_step,
&ux_stark_transfer_6_step,
&ux_stark_transfer_7_step
);
#endif

View File

@@ -0,0 +1,54 @@
#ifdef HAVE_STARKWARE
#include "shared_context.h"
#include "apdu_constants.h"
#include "stark_utils.h"
#include "ui_flow.h"
#include "ui_callbacks.h"
void handleStarkwareUnsafeSign(uint8_t p1, uint8_t p2, uint8_t *dataBuffer, uint16_t dataLength, unsigned int *flags, unsigned int *tx) {
uint32_t i;
uint8_t privateKeyData[32];
cx_ecfp_public_key_t publicKey;
cx_ecfp_private_key_t privateKey;
uint8_t bip32PathLength = *(dataBuffer);
uint8_t offset = 1;
// Initial checks
if (appState != APP_STATE_IDLE) {
reset_app_context();
}
if ((bip32PathLength < 0x01) ||
(bip32PathLength > MAX_BIP32_PATH)) {
PRINTF("Invalid path\n");
THROW(0x6a80);
}
if ((p1 != 0) || (p2 != 0)) {
THROW(0x6B00);
}
if (dataLength != 32 + 4 * bip32PathLength + 1) {
THROW(0x6700);
}
tmpCtx.transactionContext.pathLength = bip32PathLength;
for (i = 0; i < bip32PathLength; i++) {
tmpCtx.transactionContext.bip32Path[i] = U4BE(dataBuffer, offset);
PRINTF("Storing path %d %d\n", i, tmpCtx.transactionContext.bip32Path[i]);
offset += 4;
}
memmove(dataContext.starkContext.w2, dataBuffer + offset, 32);
io_seproxyhal_io_heartbeat();
starkDerivePrivateKey(tmpCtx.transactionContext.bip32Path, bip32PathLength, privateKeyData);
cx_ecfp_init_private_key(CX_CURVE_Stark256, privateKeyData, 32, &privateKey);
io_seproxyhal_io_heartbeat();
cx_ecfp_generate_pair(CX_CURVE_Stark256, &publicKey, &privateKey, 1);
memset(&privateKey, 0, sizeof(privateKey));
memset(privateKeyData, 0, sizeof(privateKeyData));
io_seproxyhal_io_heartbeat();
memmove(dataContext.starkContext.w1, publicKey.W + 1, 32);
ux_flow_init(0, ux_stark_unsafe_sign_flow, NULL);
*flags |= IO_ASYNCH_REPLY;
}
#endif

View File

@@ -0,0 +1,32 @@
#ifdef HAVE_STARKWARE
#include "shared_context.h"
#include "stark_utils.h"
#include "ui_callbacks.h"
unsigned int io_seproxyhal_touch_stark_unsafe_sign_ok(const bagl_element_t *e) {
cx_ecfp_private_key_t privateKey;
uint8_t privateKeyData[32];
uint8_t signature[72];
unsigned int info = 0;
uint32_t tx = 0;
io_seproxyhal_io_heartbeat();
starkDerivePrivateKey(tmpCtx.transactionContext.bip32Path, tmpCtx.transactionContext.pathLength, privateKeyData);
io_seproxyhal_io_heartbeat();
cx_ecfp_init_private_key(CX_CURVE_Stark256, privateKeyData, 32, &privateKey);
cx_ecdsa_sign(&privateKey, CX_RND_RFC6979 | CX_LAST, CX_SHA256,
dataContext.starkContext.w2, sizeof(dataContext.starkContext.w2), signature, sizeof(signature), &info);
G_io_apdu_buffer[0] = 0;
format_signature_out(signature);
tx = 65;
G_io_apdu_buffer[tx++] = 0x90;
G_io_apdu_buffer[tx++] = 0x00;
reset_app_context();
// Send back the response, do not restart the event loop
io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, tx);
// Display back the original UX
ui_idle();
return 0; // do not redraw the widget
}
#endif

View File

@@ -0,0 +1,69 @@
#ifdef HAVE_STARKWARE
#include "shared_context.h"
#include "ui_callbacks.h"
unsigned int io_seproxyhal_touch_stark_unsafe_sign_ok(const bagl_element_t *e);
void stark_unsafe_sign_display_account() {
snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "0x%.*H", 32, dataContext.starkContext.w1);
}
void stark_unsafe_sign_display_hash() {
snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "0x%.*H", 32, dataContext.starkContext.w2);
}
UX_STEP_NOCB(ux_stark_unsafe_sign_1_step,
pnn,
{
&C_icon_warning,
"Unsafe",
"Stark Sign",
});
UX_STEP_NOCB_INIT(
ux_stark_unsafe_sign_2_step,
bnnn_paging,
stark_unsafe_sign_display_account(),
{
.title = "From Account",
.text = strings.tmp.tmp
});
UX_STEP_NOCB_INIT(
ux_stark_unsafe_sign_3_step,
bnnn_paging,
stark_unsafe_sign_display_hash(),
{
.title = "Hash",
.text = strings.tmp.tmp
});
UX_STEP_CB(
ux_stark_unsafe_sign_4_step,
pbb,
io_seproxyhal_touch_stark_unsafe_sign_ok(NULL),
{
&C_icon_validate_14,
"Accept",
"and send",
});
UX_STEP_CB(
ux_stark_unsafe_sign_5_step,
pb,
io_seproxyhal_touch_tx_cancel(NULL),
{
&C_icon_crossmark,
"Reject",
});
UX_FLOW(ux_stark_unsafe_sign_flow,
&ux_stark_unsafe_sign_1_step,
&ux_stark_unsafe_sign_2_step,
&ux_stark_unsafe_sign_3_step,
&ux_stark_unsafe_sign_4_step,
&ux_stark_unsafe_sign_5_step
);
#endif