Compare commits

..

No commits in common. "19fd5611b23b383090add98c46764b6ab152770175711550738099fcff6a29e7" and "fba6d6bba07860261ca304fa63cfde8fe46bc6f0a7629ff07e145fe9cec99fd7" have entirely different histories.

2 changed files with 38 additions and 90 deletions

View File

@ -8,6 +8,9 @@
#include <Arduino_GFX_Library.h> #include <Arduino_GFX_Library.h>
#include <TouchDrvCSTXXX.hpp> #include <TouchDrvCSTXXX.hpp>
#include <mbedtls/sha256.h> #include <mbedtls/sha256.h>
extern "C" int ge25519_is_canonical(const unsigned char *s);
extern "C" int ge25519_is_on_curve(const unsigned char *p);
#include <mbedtls/base64.h> #include <mbedtls/base64.h>
#include <Ed25519.h> #include <Ed25519.h>
#include <sodium.h> #include <sodium.h>
@ -35,17 +38,6 @@
#define TAP_CANCEL_THRESHOLD 18 #define TAP_CANCEL_THRESHOLD 18
#define MAX_SCAN_RESULTS 8 #define MAX_SCAN_RESULTS 8
#define MAX_SAVED_WIFI_NETWORKS 8 #define MAX_SAVED_WIFI_NETWORKS 8
extern "C" {
typedef int32_t fe25519[10];
typedef struct {
fe25519 X;
fe25519 Y;
fe25519 Z;
fe25519 T;
} ge25519_p3;
int ge25519_frombytes(ge25519_p3 *h, const unsigned char *s);
}
#define WIFI_CONNECT_TIMEOUT_MS 12000 #define WIFI_CONNECT_TIMEOUT_MS 12000
#define WIFI_RECONNECT_FAST_MS 10000 #define WIFI_RECONNECT_FAST_MS 10000
#define WIFI_RECONNECT_SLOW_MS 30000 #define WIFI_RECONNECT_SLOW_MS 30000
@ -271,11 +263,6 @@ static String gLastRegisterDiagStatus = "none";
static String gLastRegisterDiagSummary; static String gLastRegisterDiagSummary;
static String gLastRegisterDiagDetails; static String gLastRegisterDiagDetails;
static String gLastRegisterDiagTime; static String gLastRegisterDiagTime;
static String gRegisterTriggerSource = "manual";
static unsigned long gBootMillis = 0;
static bool gAutoRegisterTestArmed = true;
static bool gAutoRegisterTestStarted = false;
static bool gAutoRegisterTestFinished = false;
static String gSerialCommandBuffer; static String gSerialCommandBuffer;
static String gShineSessionId; static String gShineSessionId;
static String gShineSessionKey; static String gShineSessionKey;
@ -428,7 +415,6 @@ static bool signMessageEd25519(const std::vector<uint8_t> &message, const uint8_
static String encodeTransactionBase64(const uint8_t signature[64], const std::vector<uint8_t> &message); static String encodeTransactionBase64(const uint8_t signature[64], const std::vector<uint8_t> &message);
static bool awaitTransactionConfirmation(const String &signatureB58, String &messageOut); static bool awaitTransactionConfirmation(const String &signatureB58, String &messageOut);
static bool registerHomeserverOnSolana(String &messageOut); static bool registerHomeserverOnSolana(String &messageOut);
static void executeRegisterAccountFlow(const char *triggerSource, bool showResultScreen);
static void loadRegisterDiagDetailsFromPrefs(); static void loadRegisterDiagDetailsFromPrefs();
static void saveRegisterDiagDetailsToPrefs(const String &details); static void saveRegisterDiagDetailsToPrefs(const String &details);
static void clearRegisterDiagDetailsFromPrefs(); static void clearRegisterDiagDetailsFromPrefs();
@ -674,18 +660,6 @@ static String bytesToBase64String(const uint8_t *data, size_t len) {
return base64Std(data, len); return base64Std(data, len);
} }
static String bytesToHexString(const uint8_t *data, size_t len) {
static const char *kHex = "0123456789abcdef";
String out;
out.reserve(len * 2);
for (size_t i = 0; i < len; ++i) {
uint8_t v = data[i];
out += kHex[(v >> 4) & 0x0F];
out += kHex[v & 0x0F];
}
return out;
}
static String normalizeLoginValue(const String &value) { static String normalizeLoginValue(const String &value) {
String out = value; String out = value;
out.trim(); out.trim();
@ -944,8 +918,9 @@ static bool findProgramAddress(const std::vector<std::vector<uint8_t>> &seeds, c
reinterpret_cast<const unsigned char *>(kProgramDerivedAddressMarker), reinterpret_cast<const unsigned char *>(kProgramDerivedAddressMarker),
strlen(kProgramDerivedAddressMarker)); strlen(kProgramDerivedAddressMarker));
crypto_hash_sha256_final(&st, out32); crypto_hash_sha256_final(&st, out32);
ge25519_p3 point; bool isCanonical = ge25519_is_canonical(out32) != 0;
if (ge25519_frombytes(&point, out32) != 0) { bool isOnCurve = ge25519_is_on_curve(out32) != 0;
if (!(isCanonical && isOnCurve)) {
return true; return true;
} }
} }
@ -1230,7 +1205,7 @@ static std::vector<uint8_t> buildUnsignedCreateRecord(
out.push_back(kBlockTypeServerProfile); out.push_back(kBlockTypeServerProfile);
out.push_back(0); out.push_back(0);
out.push_back(1); out.push_back(1);
out.push_back(0); out.push_back(1);
out.push_back(0); out.push_back(0);
pushStrU8(out, serverAddress); pushStrU8(out, serverAddress);
out.push_back(0); out.push_back(0);
@ -1543,11 +1518,11 @@ static std::vector<uint8_t> buildLegacyMessage(
accountKeys.emplace_back(userPda, userPda + 32); accountKeys.emplace_back(userPda, userPda + 32);
accountKeys.emplace_back(inflowVault, inflowVault + 32); accountKeys.emplace_back(inflowVault, inflowVault + 32);
accountKeys.emplace_back(systemProgram, systemProgram + 32); accountKeys.emplace_back(systemProgram, systemProgram + 32);
accountKeys.emplace_back(loginGuardProgram, loginGuardProgram + 32); accountKeys.emplace_back(sysvarInstructions, sysvarInstructions + 32);
accountKeys.emplace_back(economyConfig, economyConfig + 32); accountKeys.emplace_back(economyConfig, economyConfig + 32);
accountKeys.emplace_back(loginGuardProgram, loginGuardProgram + 32);
accountKeys.emplace_back(ed25519Program, ed25519Program + 32); accountKeys.emplace_back(ed25519Program, ed25519Program + 32);
accountKeys.emplace_back(usersProgram, usersProgram + 32); accountKeys.emplace_back(usersProgram, usersProgram + 32);
accountKeys.emplace_back(sysvarInstructions, sysvarInstructions + 32);
std::vector<uint8_t> msg; std::vector<uint8_t> msg;
msg.reserve(512); msg.reserve(512);
@ -1561,25 +1536,25 @@ static std::vector<uint8_t> buildLegacyMessage(
msg.insert(msg.end(), recentBlockhash, recentBlockhash + 32); msg.insert(msg.end(), recentBlockhash, recentBlockhash + 32);
shortVecEncode(3, msg); shortVecEncode(3, msg);
msg.push_back(6); msg.push_back(7);
msg.push_back(0); msg.push_back(0);
shortVecEncode(edRootData.size(), msg); shortVecEncode(edRootData.size(), msg);
msg.insert(msg.end(), edRootData.begin(), edRootData.end()); msg.insert(msg.end(), edRootData.begin(), edRootData.end());
msg.push_back(6); msg.push_back(7);
msg.push_back(0); msg.push_back(0);
shortVecEncode(edBchData.size(), msg); shortVecEncode(edBchData.size(), msg);
msg.insert(msg.end(), edBchData.begin(), edBchData.end()); msg.insert(msg.end(), edBchData.begin(), edBchData.end());
msg.push_back(7); msg.push_back(8);
msg.push_back(7); msg.push_back(7);
msg.push_back(0); msg.push_back(0);
msg.push_back(1); msg.push_back(1);
msg.push_back(3); msg.push_back(3);
msg.push_back(2); msg.push_back(2);
msg.push_back(8);
msg.push_back(5);
msg.push_back(4); msg.push_back(4);
msg.push_back(5);
msg.push_back(6);
shortVecEncode(createData.size(), msg); shortVecEncode(createData.size(), msg);
msg.insert(msg.end(), createData.begin(), createData.end()); msg.insert(msg.end(), createData.begin(), createData.end());
return msg; return msg;
@ -1631,9 +1606,6 @@ static bool registerHomeserverOnSolana(String &messageOut) {
}; };
String cleanLogin = normalizeLoginValue(gLoginValue); String cleanLogin = normalizeLoginValue(gLoginValue);
diagDetails += String("trigger=") + gRegisterTriggerSource + "\n";
diagDetails += String("boot_millis=") + String(gBootMillis) + "\n";
diagDetails += String("test_uptime_ms=") + String(millis()) + "\n";
diagDetails += String("login=") + cleanLogin + "\n"; diagDetails += String("login=") + cleanLogin + "\n";
diagDetails += String("rpc=") + gSolanaRpcUrl + "\n"; diagDetails += String("rpc=") + gSolanaRpcUrl + "\n";
diagDetails += String("shine_server=") + gShineServerUrl + "\n"; diagDetails += String("shine_server=") + gShineServerUrl + "\n";
@ -1745,7 +1717,6 @@ static bool registerHomeserverOnSolana(String &messageOut) {
diagDetails += String("device_pub=") + bytesToBase58(devicePub, 32) + "\n"; diagDetails += String("device_pub=") + bytesToBase58(devicePub, 32) + "\n";
String blockchainName = cleanLogin + "-001"; String blockchainName = cleanLogin + "-001";
diagDetails += String("blockchain_name=") + blockchainName + "\n";
std::vector<uint8_t> lastBlockState = buildLastBlockStateBytes(cleanLogin, blockchainName); std::vector<uint8_t> lastBlockState = buildLastBlockStateBytes(cleanLogin, blockchainName);
uint8_t lastBlockHash[32]; uint8_t lastBlockHash[32];
uint8_t lastBlockSignature[64]; uint8_t lastBlockSignature[64];
@ -1753,11 +1724,8 @@ static bool registerHomeserverOnSolana(String &messageOut) {
if (!signMessageEd25519(std::vector<uint8_t>(lastBlockHash, lastBlockHash + 32), blockchainSec, lastBlockSignature)) { if (!signMessageEd25519(std::vector<uint8_t>(lastBlockHash, lastBlockHash + 32), blockchainSec, lastBlockSignature)) {
return failWithDiag("Failed to sign LastBlockState"); return failWithDiag("Failed to sign LastBlockState");
} }
diagDetails += String("last_block_hash=") + bytesToHexString(lastBlockHash, 32) + "\n";
diagDetails += String("last_block_signature_b64=") + bytesToBase64String(lastBlockSignature, 64) + "\n";
uint64_t createdAtMs = shineNowMs(); uint64_t createdAtMs = shineNowMs();
diagDetails += String("created_at_ms=") + String((unsigned long long)createdAtMs) + "\n";
std::vector<uint8_t> unsignedRecord = buildUnsignedCreateRecord( std::vector<uint8_t> unsignedRecord = buildUnsignedCreateRecord(
cleanLogin, blockchainName, gShineServerUrl, cleanLogin, blockchainName, gShineServerUrl,
rootPub, devicePub, blockchainPub, rootPub, devicePub, blockchainPub,
@ -1768,9 +1736,6 @@ static bool registerHomeserverOnSolana(String &messageOut) {
if (!signMessageEd25519(std::vector<uint8_t>(unsignedHash, unsignedHash + 32), rootSec, rootSignature)) { if (!signMessageEd25519(std::vector<uint8_t>(unsignedHash, unsignedHash + 32), rootSec, rootSignature)) {
return failWithDiag("Failed to sign PDA record"); return failWithDiag("Failed to sign PDA record");
} }
diagDetails += String("unsigned_record_len=") + String((unsigned long)unsignedRecord.size()) + "\n";
diagDetails += String("unsigned_record_hash=") + bytesToHexString(unsignedHash, 32) + "\n";
diagDetails += String("root_signature_b64=") + bytesToBase64String(rootSignature, 64) + "\n";
std::vector<uint8_t> createData = buildCreateInstructionData( std::vector<uint8_t> createData = buildCreateInstructionData(
cleanLogin, blockchainName, gShineServerUrl, cleanLogin, blockchainName, gShineServerUrl,
@ -1852,31 +1817,6 @@ static bool registerHomeserverOnSolana(String &messageOut) {
return true; return true;
} }
static void executeRegisterAccountFlow(const char *triggerSource, bool showResultScreen) {
gRegisterTriggerSource = triggerSource ? String(triggerSource) : String("manual");
prepareRegisterAccountScreen();
String registerMessage;
if (registerHomeserverOnSolana(registerMessage)) {
gRegisterResultSuccess = true;
gRegisterResultMessage = registerMessage;
gRegisterResultDetails = String("user_pda and tx signature were saved");
gAccountStatusMessage = "Registration completed";
} else {
gRegisterResultSuccess = false;
gRegisterResultMessage = registerMessage;
gRegisterResultDetails = "";
gAccountStatusMessage = registerMessage;
}
gRegisterConfirmMessage = "";
gRegisterConfirmBalanceLine = "";
gRegisterConfirmPdaLine = "";
gRegisterConfirmHomeserverLine = "";
gRegisterConfirmCanSubmit = false;
if (showResultScreen) {
showScreen(SCREEN_REGISTER_ACCOUNT_RESULT);
}
}
static void prepareRegisterAccountScreen() { static void prepareRegisterAccountScreen() {
gRegisterResultMessage = ""; gRegisterResultMessage = "";
gRegisterResultDetails = ""; gRegisterResultDetails = "";
@ -2937,7 +2877,7 @@ static void loadRegisterDiagDetailsFromPrefs() {
static void saveRegisterDiagDetailsToPrefs(const String &details) { static void saveRegisterDiagDetailsToPrefs(const String &details) {
const int chunkSize = 1400; const int chunkSize = 1400;
const int maxChunks = 20; const int maxChunks = 12;
gPrefs.remove("reg_diag_details"); gPrefs.remove("reg_diag_details");
for (int i = 0; i < maxChunks; ++i) { for (int i = 0; i < maxChunks; ++i) {
String key = String("rdd") + i; String key = String("rdd") + i;
@ -2969,7 +2909,7 @@ static void saveRegisterDiagDetailsToPrefs(const String &details) {
static void clearRegisterDiagDetailsFromPrefs() { static void clearRegisterDiagDetailsFromPrefs() {
gPrefs.remove("reg_diag_details"); gPrefs.remove("reg_diag_details");
gPrefs.remove("rddn"); gPrefs.remove("rddn");
for (int i = 0; i < 20; ++i) { for (int i = 0; i < 12; ++i) {
String key = String("rdd") + i; String key = String("rdd") + i;
gPrefs.remove(key.c_str()); gPrefs.remove(key.c_str());
} }
@ -3531,9 +3471,27 @@ static void actionButtonCb(lv_event_t *event) {
prepareRegisterAccountScreen(); prepareRegisterAccountScreen();
showScreen(SCREEN_REGISTER_ACCOUNT_CONFIRM); showScreen(SCREEN_REGISTER_ACCOUNT_CONFIRM);
break; break;
case ACTION_REGISTER_ACCOUNT_EXECUTE: case ACTION_REGISTER_ACCOUNT_EXECUTE: {
executeRegisterAccountFlow("manual", true); String registerMessage;
if (registerHomeserverOnSolana(registerMessage)) {
gRegisterResultSuccess = true;
gRegisterResultMessage = registerMessage;
gRegisterResultDetails = String("user_pda and tx signature were saved");
gAccountStatusMessage = "Registration completed";
} else {
gRegisterResultSuccess = false;
gRegisterResultMessage = registerMessage;
gRegisterResultDetails = "";
gAccountStatusMessage = registerMessage;
}
gRegisterConfirmMessage = "";
gRegisterConfirmBalanceLine = "";
gRegisterConfirmPdaLine = "";
gRegisterConfirmHomeserverLine = "";
gRegisterConfirmCanSubmit = false;
showScreen(SCREEN_REGISTER_ACCOUNT_RESULT);
break; break;
}
case ACTION_OPEN_WIFI: case ACTION_OPEN_WIFI:
gWifiViewMode = WIFI_VIEW_OVERVIEW; gWifiViewMode = WIFI_VIEW_OVERVIEW;
showScreen(SCREEN_WIFI); showScreen(SCREEN_WIFI);
@ -4411,7 +4369,6 @@ static void handleSwipe(SwipeDirection swipe) {
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
sodium_init(); sodium_init();
gBootMillis = millis();
Wire.begin(PIN_I2C_SDA, PIN_I2C_SCL); Wire.begin(PIN_I2C_SDA, PIN_I2C_SCL);
initPowerManagement(); initPowerManagement();
@ -4473,15 +4430,6 @@ void loop() {
manageAccountPdaRefresh(); manageAccountPdaRefresh();
manageShineConnection(); manageShineConnection();
if (gAutoRegisterTestArmed && !gAutoRegisterTestStarted && millis() - gBootMillis >= 15000UL) {
gAutoRegisterTestStarted = true;
gAutoRegisterTestArmed = false;
Serial.println("AUTO_REGISTER_TEST_BEGIN");
executeRegisterAccountFlow("auto-boot-15s", false);
gAutoRegisterTestFinished = true;
Serial.println("AUTO_REGISTER_TEST_END");
}
static unsigned long lastHomeRefreshMs = 0; static unsigned long lastHomeRefreshMs = 0;
if (gCurrentScreen == SCREEN_HOME && !gTouchDown && millis() - lastHomeRefreshMs >= HOME_REFRESH_MS) { if (gCurrentScreen == SCREEN_HOME && !gTouchDown && millis() - lastHomeRefreshMs >= HOME_REFRESH_MS) {
lastHomeRefreshMs = millis(); lastHomeRefreshMs = millis();

View File

@ -1,2 +1,2 @@
client.version=1.2.175 client.version=1.2.171
server.version=1.2.164 server.version=1.2.160