Миграция PDA на client.key

This commit is contained in:
AidarKC
2026-06-22 21:57:09 +04:00
parent ba348dafb3
commit 5c92b6a734
133 changed files with 941 additions and 30531 deletions
@@ -11,7 +11,7 @@
* legacy(empty password):
* secret = SHA256(base64(SHA256(password)) + "master.secret")
* keyPair_i = Ed25519(SHA256(base64(secret) + "|" + suffix_i))
* suffixes = ["root.key", "bch.key", "dev.key"]
* suffixes = ["root.key", "blockchain.key", "client.key"]
*
* Плата: Waveshare ESP32-S3-Touch-AMOLED-2.16
* SD : SDMMC 1-bit CLK=GPIO2, CMD=GPIO1, D0=GPIO3
@@ -116,8 +116,8 @@ static bool gKbNums = false;
// ═══════════════════════════════════════════════════════════
struct KeyPair { uint8_t pub[32]; uint8_t priv[32]; };
static KeyPair gKeys[3];
static const char * KEY_SUFFIXES[3] = {"root.key", "bch.key", "dev.key"};
static const char * KEY_LABELS[3] = {"root.key", "bch.key", "dev.key"};
static const char * KEY_SUFFIXES[3] = {"root.key", "blockchain.key", "client.key"};
static const char * KEY_LABELS[3] = {"root.key", "blockchain.key", "client.key"};
static uint32_t gElapsedSec = 0;
// Base58 представления (43-44 символа для 32 байт + \0)
@@ -81,7 +81,7 @@ static const char *kPaymentsInflowSeed = "shine_payments_inflow_vault";
static const char *kLastBlockPrefix = "SHiNE_LAST_BLOCK";
static const char *kProgramDerivedAddressMarker = "ProgramDerivedAddress";
static const uint8_t kBlockTypeRootKey = 1;
static const uint8_t kBlockTypeDeviceKey = 2;
static const uint8_t kBlockTypeClientKey = 2;
static const uint8_t kBlockTypeBlockchainRegistry = 3;
static const uint8_t kBlockTypeServerProfile = 30;
static const uint8_t kBlockTypeAccessServers = 40;
@@ -230,7 +230,7 @@ struct ShinePdaUserState {
uint8_t sessionsMode = 1;
uint8_t trustedCount = 0;
uint8_t rootKey32[32] = {};
uint8_t deviceKey32[32] = {};
uint8_t clientKey32[32] = {};
uint8_t blockchainKey32[32] = {};
String blockchainName;
uint64_t paidLimitBytes = 0;
@@ -542,7 +542,7 @@ static std::vector<uint8_t> buildUnsignedCreateRecord(
const String &blockchainName,
const String &serverAddress,
const uint8_t rootPub[32],
const uint8_t devicePub[32],
const uint8_t clientPub[32],
const uint8_t blockchainPub[32],
const uint8_t lastBlockSignature[64],
uint64_t paidLimitBytes,
@@ -552,7 +552,7 @@ static std::vector<uint8_t> buildCreateInstructionData(
const String &blockchainName,
const String &serverAddress,
const uint8_t rootPub[32],
const uint8_t devicePub[32],
const uint8_t clientPub[32],
const uint8_t blockchainPub[32],
const uint8_t lastBlockSignature[64],
const uint8_t rootSignature[64],
@@ -566,7 +566,7 @@ static std::vector<uint8_t> buildUpdateInstructionData(const ShinePdaUserState &
const uint8_t rootSignature64[64]);
static std::vector<uint8_t> buildLegacyMessage(
const uint8_t recentBlockhash[32],
const uint8_t devicePub[32],
const uint8_t clientPub[32],
const uint8_t userPda[32],
const uint8_t inflowVault[32],
const uint8_t economyConfig[32],
@@ -575,7 +575,7 @@ static std::vector<uint8_t> buildLegacyMessage(
const std::vector<uint8_t> &createData);
static std::vector<uint8_t> buildUpdateLegacyMessage(
const uint8_t recentBlockhash[32],
const uint8_t devicePub[32],
const uint8_t clientPub[32],
const uint8_t userPda[32],
const uint8_t inflowVault[32],
const uint8_t economyConfig[32],
@@ -1234,8 +1234,8 @@ static void refreshDerivedKeys() {
return;
}
deriveKeyPairFromSecretSuffix(gSecretBytes, "root.key", gRootPubB58, gRootPrivB58);
deriveKeyPairFromSecretSuffix(gSecretBytes, "bch.key", gBlockchainPubB58, gBlockchainPrivB58);
deriveKeyPairFromSecretSuffix(gSecretBytes, "dev.key", gDevicePubB58, gDevicePrivB58);
deriveKeyPairFromSecretSuffix(gSecretBytes, "blockchain.key", gBlockchainPubB58, gBlockchainPrivB58);
deriveKeyPairFromSecretSuffix(gSecretBytes, "client.key", gDevicePubB58, gDevicePrivB58);
deriveKeyPairFromSecretSuffix(gSecretBytes, homeserverKeySuffix(), gHomeserverPubB58, gHomeserverPrivB58);
String customName = gCustomWalletName;
customName.trim();
@@ -1255,7 +1255,7 @@ static String selectedWalletDisplayName() {
}
case WALLET_SELECTION_DEVICE:
default:
return "DeviceKey";
return "ClientKey";
}
}
@@ -1267,7 +1267,7 @@ static String selectedWalletTypeCode() {
return "custom";
case WALLET_SELECTION_DEVICE:
default:
return "dev.key";
return "client.key";
}
}
@@ -1282,7 +1282,7 @@ static String selectedWalletDerivationSuffix() {
}
case WALLET_SELECTION_DEVICE:
default:
return "dev.key";
return "client.key";
}
}
@@ -1759,9 +1759,9 @@ static std::vector<uint8_t> serializeUnsignedRecordState(const ShinePdaUserState
out.push_back(0);
pushFixed(out, state.rootKey32, 32);
out.push_back(kBlockTypeDeviceKey);
out.push_back(kBlockTypeClientKey);
out.push_back(0);
pushFixed(out, state.deviceKey32, 32);
pushFixed(out, state.clientKey32, 32);
out.push_back(kBlockTypeBlockchainRegistry);
out.push_back(0);
@@ -1837,7 +1837,7 @@ static std::vector<uint8_t> buildUpdateInstructionData(const ShinePdaUserState &
pushU32LE(out, nextVersion);
pushFixed(out, prevHash32, 32);
pushU64LE(out, 0);
pushFixed(out, state.deviceKey32, 32);
pushFixed(out, state.clientKey32, 32);
pushFixed(out, state.blockchainKey32, 32);
pushStrU8(out, state.blockchainName);
pushU64LE(out, state.usedBytes);
@@ -1882,7 +1882,7 @@ static std::vector<uint8_t> buildUnsignedCreateRecord(
const String &blockchainName,
const String &serverAddress,
const uint8_t rootPub[32],
const uint8_t devicePub[32],
const uint8_t clientPub[32],
const uint8_t blockchainPub[32],
const uint8_t lastBlockSignature[64],
uint64_t paidLimitBytes,
@@ -1905,9 +1905,9 @@ static std::vector<uint8_t> buildUnsignedCreateRecord(
out.push_back(0);
pushFixed(out, rootPub, 32);
out.push_back(kBlockTypeDeviceKey);
out.push_back(kBlockTypeClientKey);
out.push_back(0);
pushFixed(out, devicePub, 32);
pushFixed(out, clientPub, 32);
out.push_back(kBlockTypeBlockchainRegistry);
out.push_back(0);
@@ -1954,7 +1954,7 @@ static std::vector<uint8_t> buildCreateInstructionData(
const String &blockchainName,
const String &serverAddress,
const uint8_t rootPub[32],
const uint8_t devicePub[32],
const uint8_t clientPub[32],
const uint8_t blockchainPub[32],
const uint8_t lastBlockSignature[64],
const uint8_t rootSignature[64],
@@ -1966,7 +1966,7 @@ static std::vector<uint8_t> buildCreateInstructionData(
pushFixed(out, rootPub, 32);
pushU64LE(out, createdAtMs);
pushU64LE(out, 0);
pushFixed(out, devicePub, 32);
pushFixed(out, clientPub, 32);
pushFixed(out, blockchainPub, 32);
pushStrU8(out, blockchainName);
pushU64LE(out, 0);
@@ -2215,7 +2215,7 @@ static bool simulateTransactionForError(const String &txBase64, String &messageO
static std::vector<uint8_t> buildLegacyMessage(
const uint8_t recentBlockhash[32],
const uint8_t devicePub[32],
const uint8_t clientPub[32],
const uint8_t userPda[32],
const uint8_t inflowVault[32],
const uint8_t economyConfig[32],
@@ -2234,7 +2234,7 @@ static std::vector<uint8_t> buildLegacyMessage(
base58ToFixed32(kShineLoginGuardProgramId, loginGuardProgram);
std::vector<std::vector<uint8_t>> accountKeys;
accountKeys.emplace_back(devicePub, devicePub + 32);
accountKeys.emplace_back(clientPub, clientPub + 32);
accountKeys.emplace_back(userPda, userPda + 32);
accountKeys.emplace_back(inflowVault, inflowVault + 32);
accountKeys.emplace_back(systemProgram, systemProgram + 32);
@@ -2282,7 +2282,7 @@ static std::vector<uint8_t> buildLegacyMessage(
static std::vector<uint8_t> buildUpdateLegacyMessage(
const uint8_t recentBlockhash[32],
const uint8_t devicePub[32],
const uint8_t clientPub[32],
const uint8_t userPda[32],
const uint8_t inflowVault[32],
const uint8_t economyConfig[32],
@@ -2299,7 +2299,7 @@ static std::vector<uint8_t> buildUpdateLegacyMessage(
base58ToFixed32(kSysvarInstructionsId, sysvarInstructions);
std::vector<std::vector<uint8_t>> accountKeys;
accountKeys.emplace_back(devicePub, devicePub + 32);
accountKeys.emplace_back(clientPub, clientPub + 32);
accountKeys.emplace_back(userPda, userPda + 32);
accountKeys.emplace_back(inflowVault, inflowVault + 32);
accountKeys.emplace_back(systemProgram, systemProgram + 32);
@@ -2708,17 +2708,17 @@ static bool registerHomeserverOnSolana(String &messageOut) {
uint8_t blockchainSeed[32] = {};
uint8_t blockchainPub[32] = {};
uint8_t blockchainSec[64] = {};
uint8_t deviceSeed[32] = {};
uint8_t devicePub[32] = {};
uint8_t clientSeed[32] = {};
uint8_t clientPub[32] = {};
uint8_t deviceSec[64] = {};
if (!deriveSeedKeypairFromBase58(gRootPrivB58, rootSeed, rootPub, rootSec) ||
!deriveSeedKeypairFromBase58(gBlockchainPrivB58, blockchainSeed, blockchainPub, blockchainSec) ||
!deriveSeedKeypairFromBase58(gDevicePrivB58, deviceSeed, devicePub, deviceSec)) {
!deriveSeedKeypairFromBase58(gDevicePrivB58, clientSeed, clientPub, deviceSec)) {
return failWithDiag("Failed to restore keys");
}
diagDetails += String("root_pub=") + bytesToBase58(rootPub, 32) + "\n";
diagDetails += String("blockchain_pub=") + bytesToBase58(blockchainPub, 32) + "\n";
diagDetails += String("device_pub=") + bytesToBase58(devicePub, 32) + "\n";
diagDetails += String("device_pub=") + bytesToBase58(clientPub, 32) + "\n";
String blockchainName = cleanLogin + "-001";
diagDetails += String("blockchain_name=") + blockchainName + "\n";
@@ -2736,7 +2736,7 @@ static bool registerHomeserverOnSolana(String &messageOut) {
diagDetails += String("created_at_ms=") + String((unsigned long long)createdAtMs) + "\n";
std::vector<uint8_t> unsignedRecord = buildUnsignedCreateRecord(
cleanLogin, blockchainName, gShineServerUrl,
rootPub, devicePub, blockchainPub,
rootPub, clientPub, blockchainPub,
lastBlockSignature, startBonusLimit, createdAtMs);
uint8_t unsignedHash[32];
uint8_t rootSignature[64];
@@ -2750,7 +2750,7 @@ static bool registerHomeserverOnSolana(String &messageOut) {
std::vector<uint8_t> createData = buildCreateInstructionData(
cleanLogin, blockchainName, gShineServerUrl,
rootPub, devicePub, blockchainPub,
rootPub, clientPub, blockchainPub,
lastBlockSignature, rootSignature, createdAtMs);
std::vector<uint8_t> edRootData = buildEd25519InstructionData(rootSignature, rootPub, unsignedHash);
std::vector<uint8_t> edBchData = buildEd25519InstructionData(lastBlockSignature, blockchainPub, lastBlockHash);
@@ -2765,7 +2765,7 @@ static bool registerHomeserverOnSolana(String &messageOut) {
std::vector<uint8_t> message = buildLegacyMessage(
recentBlockhash,
devicePub,
clientPub,
userPda,
inflowVault,
economyConfig,
@@ -3012,17 +3012,17 @@ static bool updateHomeserverSessionOnSolana(bool requireExisting, String &messag
uint8_t rootSeed[32] = {};
uint8_t rootPub[32] = {};
uint8_t rootSec[64] = {};
uint8_t deviceSeed[32] = {};
uint8_t devicePub[32] = {};
uint8_t clientSeed[32] = {};
uint8_t clientPub[32] = {};
uint8_t deviceSec[64] = {};
uint8_t homeserverPub[32] = {};
if (!deriveSeedKeypairFromBase58(gRootPrivB58, rootSeed, rootPub, rootSec)
|| !deriveSeedKeypairFromBase58(gDevicePrivB58, deviceSeed, devicePub, deviceSec)
|| !deriveSeedKeypairFromBase58(gDevicePrivB58, clientSeed, clientPub, deviceSec)
|| !base58ToFixed32(gHomeserverPubB58, homeserverPub)) {
return failWithDiag("Failed to restore local keys");
}
if (memcmp(devicePub, currentState.deviceKey32, 32) != 0) {
return failWithDiag("Device key does not match PDA");
if (memcmp(clientPub, currentState.clientKey32, 32) != 0) {
return failWithDiag("Client key does not match PDA");
}
uint8_t userPda[32] = {};
@@ -3048,7 +3048,7 @@ static bool updateHomeserverSessionOnSolana(bool requireExisting, String &messag
ShinePdaUserState nextState = currentState;
memcpy(nextState.rootKey32, rootPub, 32);
memcpy(nextState.deviceKey32, devicePub, 32);
memcpy(nextState.clientKey32, clientPub, 32);
nextState.updatedAtMs = shineNowMs();
nextState.recordNumber = currentState.recordNumber + 1;
if (nextState.sessionsMode == 0) {
@@ -3121,7 +3121,7 @@ static bool updateHomeserverSessionOnSolana(bool requireExisting, String &messag
std::vector<uint8_t> message = buildUpdateLegacyMessage(
recentBlockhash,
devicePub,
clientPub,
userPda,
inflowVault,
economyConfig,
@@ -3289,9 +3289,9 @@ static bool parseShineUserPdaBytes(const std::vector<uint8_t> &bytes, ShinePdaUs
}
continue;
}
if (blockType == kBlockTypeDeviceKey) {
if (!readBytes(outState.deviceKey32, 32)) {
errorOut = "Bad device key block";
if (blockType == kBlockTypeClientKey) {
if (!readBytes(outState.clientKey32, 32)) {
errorOut = "Bad client key block";
return false;
}
continue;
@@ -3520,10 +3520,10 @@ static void refreshAccountPdaStatus() {
}
uint8_t rootPub[32] = {};
uint8_t devicePub[32] = {};
uint8_t clientPub[32] = {};
uint8_t blockchainPub[32] = {};
if (!base58ToFixed32(gRootPubB58, rootPub)
|| !base58ToFixed32(gDevicePubB58, devicePub)
|| !base58ToFixed32(gDevicePubB58, clientPub)
|| !base58ToFixed32(gBlockchainPubB58, blockchainPub)) {
gAccountPdaStatus = ACCOUNT_PDA_MISMATCH;
gAccountPdaStatusMessage = "local keys invalid";
@@ -3537,8 +3537,8 @@ static void refreshAccountPdaStatus() {
mismatch = "root key mismatch";
} else if (memcmp(blockchainPub, pdaState.blockchainKey32, 32) != 0) {
mismatch = "blockchain key mismatch";
} else if (memcmp(devicePub, pdaState.deviceKey32, 32) != 0) {
mismatch = "device key mismatch";
} else if (memcmp(clientPub, pdaState.clientKey32, 32) != 0) {
mismatch = "client key mismatch";
} else if (gHomeserverValue.isEmpty()) {
mismatch = "homeserver not set";
} else {
@@ -3963,20 +3963,20 @@ static bool buildPkcs8FromSeed32(const uint8_t seed32[32], String &pkcs8B64Out)
static bool buildPairingSecretsPayload(const PairingRequestUiItem &item, String &payloadJsonOut, String &errorOut) {
payloadJsonOut = "";
errorOut = "";
uint8_t deviceSeed[32] = {};
uint8_t devicePub[32] = {};
uint8_t clientSeed[32] = {};
uint8_t clientPub[32] = {};
uint8_t deviceSec[64] = {};
if (!deriveSeedKeypairFromBase58(gDevicePrivB58, deviceSeed, devicePub, deviceSec)) {
errorOut = "Failed to derive device key";
if (!deriveSeedKeypairFromBase58(gDevicePrivB58, clientSeed, clientPub, deviceSec)) {
errorOut = "Failed to derive client key";
return false;
}
String devicePkcs8;
if (!buildPkcs8FromSeed32(deviceSeed, devicePkcs8)) {
errorOut = "Failed to encode device key";
if (!buildPkcs8FromSeed32(clientSeed, devicePkcs8)) {
errorOut = "Failed to encode client key";
return false;
}
payloadJsonOut = String("{\"v\":1,\"type\":\"shine-esp-pairing-transfer\",\"login\":\"") + jsonEscape(gLoginValue)
+ "\",\"mode\":\"device-only\",\"keys\":{\"deviceKey\":\"" + jsonEscape(devicePkcs8)
+ "\",\"mode\":\"device-only\",\"keys\":{\"clientKey\":\"" + jsonEscape(devicePkcs8)
+ "\",\"blockchainKey\":\"\",\"rootKey\":\"\"},\"payloadType\":1,\"createdAtMs\":"
+ String((unsigned long long)shineNowMs()) + "}";
return true;
@@ -3985,11 +3985,11 @@ static bool buildPairingSecretsPayload(const PairingRequestUiItem &item, String
static bool createDelegatedWalletSessionPayload(const PairingRequestUiItem &item, String &payloadJsonOut, String &errorOut) {
payloadJsonOut = "";
errorOut = "";
uint8_t deviceSeed[32] = {};
uint8_t devicePub[32] = {};
uint8_t clientSeed[32] = {};
uint8_t clientPub[32] = {};
uint8_t deviceSec[64] = {};
if (!deriveSeedKeypairFromBase58(gDevicePrivB58, deviceSeed, devicePub, deviceSec)) {
errorOut = "Failed to derive device key";
if (!deriveSeedKeypairFromBase58(gDevicePrivB58, clientSeed, clientPub, deviceSec)) {
errorOut = "Failed to derive client key";
return false;
}
@@ -4040,7 +4040,7 @@ static bool createDelegatedWalletSessionPayload(const PairingRequestUiItem &item
+ "\",\"storagePwd\":\"" + jsonEscape(storagePwd)
+ "\",\"timeMs\":" + String((unsigned long long)timeMs)
+ ",\"authNonce\":\"" + jsonEscape(authNonce)
+ "\",\"deviceKey\":\"" + jsonEscape(bytesToBase64String(devicePub, 32))
+ "\",\"clientKey\":\"" + jsonEscape(bytesToBase64String(clientPub, 32))
+ "\",\"signatureB64\":\"" + jsonEscape(bytesToBase64String(signature, 64))
+ "\",\"sessionType\":50"
+ ",\"clientPlatform\":\"" + jsonEscape(clientPlatform)
@@ -4262,13 +4262,13 @@ static bool ensureShineSessionAuthenticated(String &errorOut) {
diagDetails += String("server_time_offset_ms=") + String((long long)gShineServerTimeOffsetMs) + "\n";
}
uint8_t deviceSeed[32] = {};
uint8_t devicePub[32] = {};
uint8_t clientSeed[32] = {};
uint8_t clientPub[32] = {};
uint8_t deviceSec[64] = {};
uint8_t subSeed[32] = {};
uint8_t subPub[32] = {};
uint8_t subSec[64] = {};
if (!deriveSeedKeypairFromBase58(gDevicePrivB58, deviceSeed, devicePub, deviceSec)
if (!deriveSeedKeypairFromBase58(gDevicePrivB58, clientSeed, clientPub, deviceSec)
|| !deriveSeedKeypairFromBase58(gHomeserverPrivB58, subSeed, subPub, subSec)) {
return failWithDiag("local key derive failed");
}
@@ -4368,7 +4368,7 @@ static bool ensureShineSessionAuthenticated(String &errorOut) {
+ "\",\"storagePwd\":\"" + jsonEscape(gShineStoragePwd)
+ "\",\"timeMs\":" + String((unsigned long long)timeMs)
+ ",\"authNonce\":\"" + jsonEscape(authNonce)
+ "\",\"deviceKey\":\"" + jsonEscape(bytesToBase64String(devicePub, 32))
+ "\",\"clientKey\":\"" + jsonEscape(bytesToBase64String(clientPub, 32))
+ "\",\"signatureB64\":\"" + jsonEscape(bytesToBase64String(signature, 64))
+ "\",\"sessionType\":" + String((unsigned int)kSessionTypeHomeserver)
+ ",\"clientPlatform\":\"" + jsonEscape(kSessionClientPlatformEsp32)
@@ -4510,7 +4510,7 @@ static void loadPrefs() {
gShineServerUrl = gPrefs.getString("shine_server", "https://shineup.me");
gLoginValue = gPrefs.getString("login", "");
gHomeserverValue = gPrefs.getString("homeserver", "homeserver1");
String walletTypeStored = gPrefs.getString("wallet_type", "dev.key");
String walletTypeStored = gPrefs.getString("wallet_type", "client.key");
if (walletTypeStored == "root.key") {
gSelectedWalletType = WALLET_SELECTION_ROOT;
} else if (walletTypeStored == "custom") {
@@ -5786,7 +5786,7 @@ static void drawWalletSelectScreen() {
makeTitle("SELECT WALLET", 22, &lv_font_montserrat_24);
String currentLine = String("Current: ") + selectedWalletDisplayName();
makeBody(currentLine.c_str(), 88, 420);
String deviceLabel = String(gSelectedWalletType == WALLET_SELECTION_DEVICE ? "DeviceKey" : "DeviceKey");
String deviceLabel = String(gSelectedWalletType == WALLET_SELECTION_DEVICE ? "ClientKey" : "ClientKey");
String rootLabel = String(gSelectedWalletType == WALLET_SELECTION_ROOT ? "✓ RootKey" : "RootKey");
String customBase = gCustomWalletName;
customBase.trim();
@@ -6081,7 +6081,7 @@ static void drawPairingRequestDetailScreen() {
String question = String("Connect session ") + pairingSessionNameLabel(item) + "?";
String explain = item.requesterSessionType == 50
? "Wallet session. No keys will be transferred."
: "Client session. Only device key will be transferred. No additional keys will be sent.";
: "Client session. Only client key will be transferred. No additional keys will be sent.";
String sessionNameText = String("Session: ") + pairingSessionNameLabel(item);
String sessionKindText = String("Kind: ") + pairingSessionKindLabel(item.requesterSessionType);
@@ -6301,8 +6301,8 @@ static void drawSecretShowScreen() {
addKeyBlock("Root key priv (base58)", "sha256(base64(secret)|root.key)", gRootPrivB58);
addKeyBlock("Blockchain key (base58)", "pub from sha256(base64(secret)|bch.key)", gBlockchainPubB58);
addKeyBlock("Blockchain key priv (base58)", "sha256(base64(secret)|bch.key)", gBlockchainPrivB58);
addKeyBlock("Device key (base58)", "pub from sha256(base64(secret)|dev.key)", gDevicePubB58);
addKeyBlock("Device key priv (base58)", "sha256(base64(secret)|dev.key)", gDevicePrivB58);
addKeyBlock("Client key (base58)", "pub from sha256(base64(secret)|client.key)", gDevicePubB58);
addKeyBlock("Client key priv (base58)", "sha256(base64(secret)|client.key)", gDevicePrivB58);
addKeyBlock("Homeserver key (base58)", String("pub from sha256(base64(secret)|") + homeserverKeySuffix() + ")", gHomeserverPubB58);
addKeyBlock("Homeserver key priv (base58)", String("sha256(base64(secret)|") + homeserverKeySuffix() + ")", gHomeserverPrivB58);
} else {
@@ -228,7 +228,7 @@ struct DerivedKeyState {
uint8_t rootSk[64];
uint8_t blockchainPub[32];
uint8_t blockchainSk[64];
uint8_t devicePub[32];
uint8_t clientPub[32];
uint8_t deviceSk[64];
};
@@ -246,7 +246,7 @@ static const char *kPaymentsInflowSeed = "shine_payments_inflow_vault";
static const char *kProgramDerivedAddressMarker = "ProgramDerivedAddress";
static const char *kLastBlockPrefix = "SHiNE_LAST_BLOCK";
static const uint8_t kBlockTypeRootKey = 1;
static const uint8_t kBlockTypeDeviceKey = 2;
static const uint8_t kBlockTypeClientKey = 2;
static const uint8_t kBlockTypeBlockchainRegistry = 3;
static const uint8_t kBlockTypeServerProfile = 30;
static const uint8_t kBlockTypeAccessServers = 40;
@@ -786,8 +786,8 @@ static bool deriveKeysFromMasterSecret(const uint8_t masterSecret[32]) {
if (secretB64.length() == 0) {
return false;
}
const char *suffixes[3] = {"root.key", "bch.key", "dev.key"};
uint8_t *pubs[3] = {gDerivedKeys.rootPub, gDerivedKeys.blockchainPub, gDerivedKeys.devicePub};
const char *suffixes[3] = {"root.key", "blockchain.key", "client.key"};
uint8_t *pubs[3] = {gDerivedKeys.rootPub, gDerivedKeys.blockchainPub, gDerivedKeys.clientPub};
uint8_t *sks[3] = {gDerivedKeys.rootSk, gDerivedKeys.blockchainSk, gDerivedKeys.deviceSk};
for (int i = 0; i < 3; i++) {
String material = secretB64 + "|" + suffixes[i];
@@ -822,7 +822,7 @@ static bool restoreDerivedKeysFromSecret() {
return false;
}
gData.secretReady = true;
gData.walletAddress = bytesToBase58(gDerivedKeys.devicePub, 32);
gData.walletAddress = bytesToBase58(gDerivedKeys.clientPub, 32);
return true;
}
@@ -835,7 +835,7 @@ static bool deriveFreshSecretAndWallet() {
return false;
}
gData.secret = bytesToBase58(secret, sizeof(secret));
gData.walletAddress = bytesToBase58(gDerivedKeys.devicePub, 32);
gData.walletAddress = bytesToBase58(gDerivedKeys.clientPub, 32);
gData.secretReady = true;
return true;
}
@@ -889,7 +889,7 @@ static std::vector<uint8_t> buildUnsignedCreateRecord(
const String &blockchainName,
const String &serverAddress,
const uint8_t rootPub[32],
const uint8_t devicePub[32],
const uint8_t clientPub[32],
const uint8_t blockchainPub[32],
const uint8_t lastBlockSignature[64],
uint64_t createdAtMs) {
@@ -911,9 +911,9 @@ static std::vector<uint8_t> buildUnsignedCreateRecord(
out.push_back(0);
pushFixed(out, rootPub, 32);
out.push_back(kBlockTypeDeviceKey);
out.push_back(kBlockTypeClientKey);
out.push_back(0);
pushFixed(out, devicePub, 32);
pushFixed(out, clientPub, 32);
out.push_back(kBlockTypeBlockchainRegistry);
out.push_back(0);
@@ -960,7 +960,7 @@ static std::vector<uint8_t> buildCreateInstructionData(
const String &blockchainName,
const String &serverAddress,
const uint8_t rootPub[32],
const uint8_t devicePub[32],
const uint8_t clientPub[32],
const uint8_t blockchainPub[32],
const uint8_t lastBlockSignature[64],
const uint8_t rootSignature[64],
@@ -972,7 +972,7 @@ static std::vector<uint8_t> buildCreateInstructionData(
pushFixed(out, rootPub, 32);
pushU64LE(out, createdAtMs);
pushU64LE(out, 0);
pushFixed(out, devicePub, 32);
pushFixed(out, clientPub, 32);
pushFixed(out, blockchainPub, 32);
pushStrU8(out, blockchainName);
pushU64LE(out, 0);
@@ -1079,7 +1079,7 @@ static bool pdaAlreadyExists(const String &login, String &pdaAddress, String &me
static std::vector<uint8_t> buildLegacyMessage(
const uint8_t recentBlockhash[32],
const uint8_t devicePub[32],
const uint8_t clientPub[32],
const uint8_t userPda[32],
const uint8_t inflowVault[32],
const uint8_t economyConfig[32],
@@ -1098,7 +1098,7 @@ static std::vector<uint8_t> buildLegacyMessage(
base58ToFixed32(kShineLoginGuardProgramId, loginGuardProgram);
std::vector<std::vector<uint8_t>> accountKeys;
accountKeys.emplace_back(devicePub, devicePub + 32);
accountKeys.emplace_back(clientPub, clientPub + 32);
accountKeys.emplace_back(userPda, userPda + 32);
accountKeys.emplace_back(inflowVault, inflowVault + 32);
accountKeys.emplace_back(systemProgram, systemProgram + 32);
@@ -1244,7 +1244,7 @@ static bool registerHomeserverOnSolana(String &messageOut) {
uint64_t createdAtMs = (uint64_t)millis() + 1704067200000ULL;
std::vector<uint8_t> unsignedRecord = buildUnsignedCreateRecord(
gData.login, blockchainName, gData.wsUrl,
gDerivedKeys.rootPub, gDerivedKeys.devicePub, gDerivedKeys.blockchainPub,
gDerivedKeys.rootPub, gDerivedKeys.clientPub, gDerivedKeys.blockchainPub,
lastBlockSignature, createdAtMs);
uint8_t unsignedHash[32];
uint8_t rootSignature[64];
@@ -1256,7 +1256,7 @@ static bool registerHomeserverOnSolana(String &messageOut) {
std::vector<uint8_t> createData = buildCreateInstructionData(
gData.login, blockchainName, gData.wsUrl,
gDerivedKeys.rootPub, gDerivedKeys.devicePub, gDerivedKeys.blockchainPub,
gDerivedKeys.rootPub, gDerivedKeys.clientPub, gDerivedKeys.blockchainPub,
lastBlockSignature, rootSignature, createdAtMs);
std::vector<uint8_t> edRootData = buildEd25519InstructionData(rootSignature, gDerivedKeys.rootPub, unsignedHash);
std::vector<uint8_t> edBchData = buildEd25519InstructionData(lastBlockSignature, gDerivedKeys.blockchainPub, lastBlockHash);
@@ -1269,7 +1269,7 @@ static bool registerHomeserverOnSolana(String &messageOut) {
std::vector<uint8_t> message = buildLegacyMessage(
recentBlockhash,
gDerivedKeys.devicePub,
gDerivedKeys.clientPub,
userPda,
inflowVault,
economyConfig,
@@ -2107,7 +2107,7 @@ static void drawConfirmScreen() {
String text = "Выполнить действие?";
if (gConfirmTarget == CONFIRM_REGISTER) {
title = "Регистрация";
text = "Отправить create_user_pda в Solana через device key этого устройства?";
text = "Отправить create_user_pda в Solana через client key этого устройства?";
} else if (gConfirmTarget == CONFIRM_CLEAR_ACCOUNT) {
title = "Очистка";
text = "Удалить секрет, кошелёк и статус регистрации?";