diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..53ab524
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,24 @@
+name: Build and Test
+
+on:
+ push:
+ branches: ["**"]
+ pull_request:
+ branches: ["**"]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+
+ - name: Install build tools
+ run: sudo apt-get update && sudo apt-get install -y libcurl4-openssl-dev
+
+ - name: Run make
+ run: make
+
+ - name: Confirm success
+ run: echo "Makefile executed successfully"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5d8792e..36d11b4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,9 +4,22 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## \[0.3.3] - 2026-04-01
+
+- Added new mod functions to Monocypher library (these functions are more efficient than the compact25519 ones).
+- Implemented new functions in `microsui_sign.c`, replacing the compact25519 ones.
+- Deleted the now-obsolete _compact25519 library_.
+- Refactor: rename output parameters for consistency in core functions.
+- Refactor: `private/secret key` in bytes now is renamed to `seed` for avoid imprecisions.
+- Added new Signature verification/check with public key function.
+- Added new examples (Signature and Benchmark).
+- Updated Makefiles.
+- Added GitHub `make` workflow.
+- General improvements and minor bugs fixed.
+
## \[0.3.2] - 2026-01-27
-This release introduces ***Signature Verification*** support and improves developer experience with clearer examples.
+This release introduces **_Signature Verification_** support and improves developer experience with clearer examples.
### Added
diff --git a/Makefile b/Makefile
index 3a39421..ee04764 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,6 @@ all:
fi \
done
@echo ""
- @echo "✅ All examples built successfully!"
@echo "---------------------------------------"
@for dir in $(EXAMPLE_DIRS); do \
if [ -f $$dir/Makefile ]; then \
@@ -23,4 +22,7 @@ all:
fi \
fi \
done
+ @echo ""
+ @echo "✅ All examples built successfully!"
@echo "---------------------------------------"
+
diff --git a/README.md b/README.md
index 639cc29..75637b2 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
-*MicroSui Library* is a lightweight C library designed primarily for embedded systems to interact with the ***Sui Network Blockchain***.
+_MicroSui Library_ is a lightweight C library designed primarily for embedded systems to interact with the **_Sui Network Blockchain_**.
Full compatibility with _ESP32 microcontrollers_ and _traditional desktop OS_. More device support coming soon.
@@ -11,6 +11,10 @@ This library is **_Arduino and PlatformIO Compatible_**
[](https://www.ardu-badge.com/MicroSui/ide)
[](https://registry.platformio.org/libraries/gustavogb/microsui-lib)
+### Documentation API Reference Page:
+
+[](https://docs.microsui.com)
+
## The Library:
### Build all the examples:
@@ -22,7 +26,7 @@ In Windows, macOS or Linux it will be necessary to install `cURL`:
##### In Linux:
```
-sudo apt install -y libcurl4-openssl-dev pkg-config build-essential
+sudo apt-get update && sudo apt-get install -y libcurl4-openssl-dev
```
##### In macOS:
@@ -45,7 +49,11 @@ In root, run
make
```
-You will find the `.out` binaries to run in each example folder.
+You will find the `.out` binaries to run in each example folder. Run every example with
+
+```bash
+./example.out
+```
## Project Directory Structure:
@@ -58,8 +66,6 @@ microsui-lib/
│ ├── microsui_core
│ │ ├── lib/ # Third-party dependencies
│ │ │ ├── monocypher/
-│ │ │ ├── compact25519/
-│ │ │ │ └── c25519/
│ │ │ └── jsmn/
│ │ ├── impl/ # Platform/board specific implementation
│ │ │ ├── http/
@@ -89,9 +95,7 @@ microsui-lib/
### 📦 Dependencies (`/lib`)
- `monocypher`:
- Lightweight cryptographic primitives.
-- `compact25519`:
- Ed25519 key format support.
+ Lightweight Ed25519 cryptographic primitives.
- `jsmn`:
Lightweight minimalistic JSON parser for C.
diff --git a/examples/ArduinoExamples/OfflineSign/OfflineSign.ino b/examples/ArduinoExamples/OfflineSign/OfflineSign.ino
index 38b9d7c..c760047 100644
--- a/examples/ArduinoExamples/OfflineSign/OfflineSign.ino
+++ b/examples/ArduinoExamples/OfflineSign/OfflineSign.ino
@@ -1,3 +1,4 @@
+#include
#include
// --- PRIVATE KEY (EXAMPLE / DO NOT USE IN PRODUCTION) ---
@@ -15,7 +16,7 @@ void setup() {
delay(500);
Serial.println();
- Serial.println(F("=== MicroSui ESP32 — Offline Sign Transaction Message - Obtain Sui Signature with PK ==="));
+ Serial.println(F("=== MicroSui Arduino — Offline Sign Transaction Message - Obtain Sui Signature with PK ==="));
// 1) Load keypair from Bech32 secret key
Serial.println(F("\n [1/2] Loading keypair from Bech32..."));
diff --git a/examples/ArduinoExamples/SignAndExecuteTransaction/SignAndExecuteTransaction.ino b/examples/ArduinoExamples/SignAndExecuteTransaction/SignAndExecuteTransaction.ino
index 13a4b0d..ccc15ec 100644
--- a/examples/ArduinoExamples/SignAndExecuteTransaction/SignAndExecuteTransaction.ino
+++ b/examples/ArduinoExamples/SignAndExecuteTransaction/SignAndExecuteTransaction.ino
@@ -1,3 +1,4 @@
+#include
#include
// --- WiFi credentials (example) ---
@@ -22,7 +23,8 @@ void setup() {
delay(500);
Serial.println();
- Serial.println(F("=== MicroSui ESP32 — Sign & Execute Transaction ==="));
+ Serial.println(F("=== MicroSui Arduino — Sign & Execute Transaction ==="));
+ Serial.println(F("=== Note: This example is guaranteed to work on ESP32 family, but may not work on other boards for the moment ==="));
// 1) Connect WiFi
Serial.println(F("\n [1/5] Connecting WiFi..."));
diff --git a/examples/ArduinoExamples/SignatureBechmark/SignatureBechmark.ino b/examples/ArduinoExamples/SignatureBechmark/SignatureBechmark.ino
new file mode 100644
index 0000000..4d9cf51
--- /dev/null
+++ b/examples/ArduinoExamples/SignatureBechmark/SignatureBechmark.ino
@@ -0,0 +1,65 @@
+#include
+#include
+
+// Sample Sui message and private key for testing
+const uint8_t private_key[32] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+const char *message_hex = "00000200080065cd1d0000000000202e3d52393c9035afd1ef38abd7fce2dad71f0e276b522fb274f4e14d1df974720202000101000001010300000000010100d79a4c7a655aa80cf92069bbac9666705f1d7181ff9c2d59efbc7e6ec4c3379d0180dc491e55e7caabfcdd1b0f538928d8d54107b9c1def3ed0baa3aa5106ba8674f0dd01400000000204b7e9da00f30cd1edf4d40710213c15a862e1fc175f2edb2b2c870c8559d65cdd79a4c7a655aa80cf92069bbac9666705f1d7181ff9c2d59efbc7e6ec4c3379de80300000000000040ab3c000000000000";
+
+size_t message_len;
+uint8_t message[512];
+uint8_t sui_sig[97];
+
+void setup()
+{
+ Serial.begin(115200);
+
+ message_len = strlen(message_hex) / 2; // 2 hex chars = 1 byte
+ hex_to_bytes(message_hex, message, message_len);
+}
+
+void loop()
+{
+ Serial.println(F("=== MicroSui Arduino — Bechmark Signature and Verification ==="));
+ // Creating Signature
+ Serial.println(F("\n\n Generating Signature...\n"));
+
+ unsigned long start_time = millis();
+ microsui_sign_ed25519(sui_sig, message, message_len, private_key);
+ unsigned long end_time = millis();
+ // Calculate the time taken for signing
+ unsigned long time_taken_signature = end_time - start_time;
+
+ Serial.println(F("\t Signature created successfully\n"));
+
+ // Validating Signature
+ Serial.println(F(" Verifying Signature...\n"));
+ start_time = millis();
+ int verification_result = microsui_verify_signature(sui_sig, message, message_len);
+ end_time = millis();
+ // Calculate the time taken for verification
+ unsigned long time_taken_verification = end_time - start_time;
+
+ if(verification_result == 0) {
+ Serial.println(F("\t Signature verified successfully\n\n"));
+ } else {
+ Serial.println(F("\t Signature verification failed\n"));
+ Serial.print(F("\t Error code: "));
+ Serial.println(verification_result);
+ }
+
+ Serial.print(F(" Time taken for signing: "));
+ Serial.print(time_taken_signature);
+ Serial.println(F(" ms"));
+
+ Serial.print(F(" Time taken for verification: "));
+ Serial.print(time_taken_verification);
+ Serial.println(F(" ms\n"));
+
+ Serial.println(F(" Done."));
+
+ delay(1000);
+}
\ No newline at end of file
diff --git a/examples/ArduinoExamples/ValidatingSignatures/ValidatingSignatures.ino b/examples/ArduinoExamples/ValidatingSignatures/ValidatingSignatures.ino
index 5f4ef7a..b2dffa5 100644
--- a/examples/ArduinoExamples/ValidatingSignatures/ValidatingSignatures.ino
+++ b/examples/ArduinoExamples/ValidatingSignatures/ValidatingSignatures.ino
@@ -1,3 +1,4 @@
+#include
#include
// --- PRIVATE KEY (EXAMPLE / DO NOT USE IN PRODUCTION) ---
@@ -15,7 +16,7 @@ void setup()
delay(500);
Serial.println();
- Serial.println(F("=== MicroSui ESP32 — Validation of a Sui Signature ==="));
+ Serial.println(F("=== MicroSui Arduino — Validation of a Sui Signature ==="));
// 1) Generating Keypair, and Transactions Objects
Serial.println(F("\n [1/4] Generating Keypair, and Transactions Objects..."));
@@ -47,7 +48,7 @@ void setup()
// 4) Validating Message2 with the signature (Must be FAILED)
Serial.println(F("\n [4/4] Validating Message2 with the signature (Must be FAILED)..."));
int verification_result_2 = microsui_verify_signature(sig.bytes, tx2.tx_bytes.data, tx2.tx_bytes.length);
- if (verification_result_2 == 0)
+ if (verification_result_2 != 0)
Serial.println(F("\t - Signature Verification is FAILED for Message 2 -- OK\n\n"));
Serial.println(F(" Done."));
diff --git a/examples/core_examples/benchmarks/Makefile b/examples/core_examples/benchmarks/Makefile
new file mode 100644
index 0000000..72a186d
--- /dev/null
+++ b/examples/core_examples/benchmarks/Makefile
@@ -0,0 +1,47 @@
+ROOT_DIR := ../../..
+SRC := $(ROOT_DIR)/src
+INCLUDE := $(ROOT_DIR)/include
+MICROSUI_CORE := $(ROOT_DIR)/src/microsui_core
+UTILS := $(MICROSUI_CORE)/utils
+LIB := $(MICROSUI_CORE)/lib
+
+MONOCYPHER := $(LIB)/monocypher
+JSMN := $(LIB)/jsmn
+
+HTTP_CURL_FILE = $(MICROSUI_CORE)/impl/http/http_curl.c # This Makefile needs cURL installed in the system
+HTTP_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/http/http_unsupported.c # This file is used when make is made on a system without cURL support
+HTTP_LIBS = -lcurl $(if $(filter Windows_NT,$(OS)),-lws2_32 -lbcrypt -lwldap32 -lcrypt32)
+
+WIFI_DESKTOP_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_desktop.c
+WIFI_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_unsupported.c # This file is used when make is made on a system without WiFi support
+
+CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(JSMN)
+
+SOURCES := benchmarks.c \
+ $(wildcard $(SRC)/*.c) \
+ $(wildcard $(MICROSUI_CORE)/*.c) \
+ $(wildcard $(UTILS)/*.c) \
+ $(wildcard $(JSMN)/*.c) \
+ $(wildcard $(MONOCYPHER)/*.c) \
+ $(HTTP_CURL_FILE) \
+ $(HTTP_UNSUPPORTED_FILE) \
+ $(WIFI_DESKTOP_FILE) \
+ $(WIFI_UNSUPPORTED_FILE)
+
+OUTPUT := benchmarks.out
+
+all: clean_before_build $(OUTPUT)
+
+$(OUTPUT): $(SOURCES)
+ @echo "Compiling example: $@"
+ gcc $(CFLAGS) $^ -o $@ $(HTTP_LIBS)
+
+.PHONY: clean clean_before_build
+
+clean_before_build:
+ @echo "Cleaning old binary if it exists..."
+ @rm -f $(OUTPUT)
+
+clean:
+ @echo "Removing binary..."
+ @rm -f $(OUTPUT)
\ No newline at end of file
diff --git a/examples/core_examples/benchmarks/benchmarks.c b/examples/core_examples/benchmarks/benchmarks.c
new file mode 100644
index 0000000..2d8b95b
--- /dev/null
+++ b/examples/core_examples/benchmarks/benchmarks.c
@@ -0,0 +1,95 @@
+#include
+#include
+#include
+#include
+
+#include "MicroSui.h"
+
+// Sui Message in hex format (this message must be signed)
+const char* message_hex = "00000200080065cd1d0000000000202e3d52393c9035afd1ef38abd7fce2dad71f0e276b522fb274f4e14d1df974720202000101000001010300000000010100d79a4c7a655aa80cf92069bbac9666705f1d7181ff9c2d59efbc7e6ec4c3379d0180dc491e55e7caabfcdd1b0f538928d8d54107b9c1def3ed0baa3aa5106ba8674f0dd01400000000204b7e9da00f30cd1edf4d40710213c15a862e1fc175f2edb2b2c870c8559d65cdd79a4c7a655aa80cf92069bbac9666705f1d7181ff9c2d59efbc7e6ec4c3379de80300000000000040ab3c000000000000";
+
+// You must place your seed private key (in bytes format) here.
+const uint8_t private_key_seed[32] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+uint64_t millis(void);
+
+int main() {
+ printf("\n\t\t\t --- MicroSui Operations Benchmarks ---\n");
+ printf("\n\tOriginal Message: %s", message_hex);
+
+ // Converting the message from hex to bytes
+ size_t message_len = strlen(message_hex) / 2; // 2 hex chars = 1 byte
+ uint8_t message[message_len];
+ hex_to_bytes(message_hex, message, message_len);
+
+ // Generating the Sui Signature from the message and private key
+ uint8_t sui_sig[97];
+ printf("\n\n\n Generating Signature...\n");
+
+ uint64_t start_time = millis();
+ microsui_sign_ed25519(sui_sig, message, message_len, private_key_seed);
+ uint64_t end_time = millis();
+ printf("\t Signature created successfully\n");
+
+ // Calculate the time taken for verification
+ uint64_t time_taken_signature = end_time - start_time;
+
+ // Verifying the Sui Signature
+ start_time = millis();
+ int verification_result = microsui_verify_signature(sui_sig, message, message_len);
+ end_time = millis();
+
+ // Calculate the time taken for verification
+ uint64_t time_taken_verification = end_time - start_time;
+ if(verification_result == 0) {
+ printf("\t Signature verified successfully\n\n");
+ } else {
+ printf("\t Signature verification failed\n");
+ printf("\t Error code: %d\n\n", verification_result);
+ }
+
+
+ printf("\t Benchmarks Results:\n");
+ printf("\t\t Time taken for signing: ");
+ if (time_taken_signature > 100000) {
+ printf("%llu ms\n", (unsigned long long)(time_taken_signature / 1000));
+ } else {
+ printf("%.2f ms (%llu us) \n", (double)time_taken_signature / 1000.0, (unsigned long long)time_taken_signature);
+ }
+
+ printf("\t\t Time taken for verification: ");
+ if (time_taken_verification > 100000) {
+ printf("%llu ms\n", (unsigned long long)(time_taken_verification / 1000));
+ } else {
+ printf("%.2f ms (%llu us) \n", (double)time_taken_verification / 1000.0, (unsigned long long)time_taken_verification);
+ }
+ printf("\n End of benchmarks.\n");
+
+ return 0;
+}
+
+uint64_t millis(void)
+{
+#if defined(_WIN32) || defined(_WIN64)
+ // Windows: QueryPerformanceCounter (high-resolution timer)
+ static LARGE_INTEGER freq = {0};
+ LARGE_INTEGER now;
+
+ if (freq.QuadPart == 0)
+ QueryPerformanceFrequency(&freq);
+
+ QueryPerformanceCounter(&now);
+ return (uint64_t)((now.QuadPart * 1000000) / freq.QuadPart);
+
+#else
+ // Linux y macOS: clock_gettime(CLOCK_MONOTONIC)
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return (uint64_t)(ts.tv_sec) + (ts.tv_nsec / 1000ULL);
+#endif
+}
\ No newline at end of file
diff --git a/examples/core_examples/decoding_rpc_json/Makefile b/examples/core_examples/decoding_rpc_json/Makefile
index 492ddcf..f05cc45 100644
--- a/examples/core_examples/decoding_rpc_json/Makefile
+++ b/examples/core_examples/decoding_rpc_json/Makefile
@@ -6,9 +6,7 @@ UTILS := $(MICROSUI_CORE)/utils
LIB := $(MICROSUI_CORE)/lib
MONOCYPHER := $(LIB)/monocypher
-COMPACT := $(LIB)/compact25519
-C25519 := $(COMPACT)/c25519
-JSMN := $(LIB)/JSMN
+JSMN := $(LIB)/jsmn
HTTP_CURL_FILE = $(MICROSUI_CORE)/impl/http/http_curl.c # This Makefile needs cURL installed in the system
HTTP_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/http/http_unsupported.c # This file is used when make is made on a system without cURL support
@@ -17,16 +15,14 @@ HTTP_LIBS = -lcurl $(if $(filter Windows_NT,$(OS)),-lws2_32 -lbcrypt -lwldap32 -
WIFI_DESKTOP_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_desktop.c
WIFI_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_unsupported.c # This file is used when make is made on a system without WiFi support
-CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(COMPACT) -I$(C25519) -I$(JSMN)
+CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(JSMN)
SOURCES := decoding_rpc_json.c \
- $(SRC)/*.c \
- $(MICROSUI_CORE)/*.c \
- $(UTILS)/*.c \
- $(JSMN)/*.c \
+ $(wildcard $(SRC)/*.c) \
+ $(wildcard $(MICROSUI_CORE)/*.c) \
+ $(wildcard $(UTILS)/*.c) \
+ $(wildcard $(JSMN)/*.c) \
$(wildcard $(MONOCYPHER)/*.c) \
- $(wildcard $(COMPACT)/*.c) \
- $(wildcard $(C25519)/*.c) \
$(HTTP_CURL_FILE) \
$(HTTP_UNSUPPORTED_FILE) \
$(WIFI_DESKTOP_FILE) \
@@ -48,4 +44,4 @@ clean_before_build:
clean:
@echo "Removing binary..."
- @rm -f $(OUTPUT)
+ @rm -f $(OUTPUT)
\ No newline at end of file
diff --git a/examples/core_examples/decoding_rpc_json/decoding_rpc_json.c b/examples/core_examples/decoding_rpc_json/decoding_rpc_json.c
index 648bf16..2e668c7 100644
--- a/examples/core_examples/decoding_rpc_json/decoding_rpc_json.c
+++ b/examples/core_examples/decoding_rpc_json/decoding_rpc_json.c
@@ -1,7 +1,8 @@
#include
#include
#include
-#include "microsui/rpc_json_decoder.h"
+
+#include "MicroSui.h"
int main() {
printf("\t\t Generate Sui Treansaction Block Response Object from RPC JSON Response\n\n");
diff --git a/examples/core_examples/encode_conversions/Makefile b/examples/core_examples/encode_conversions/Makefile
index 8ab9161..5d43411 100644
--- a/examples/core_examples/encode_conversions/Makefile
+++ b/examples/core_examples/encode_conversions/Makefile
@@ -6,9 +6,7 @@ UTILS := $(MICROSUI_CORE)/utils
LIB := $(MICROSUI_CORE)/lib
MONOCYPHER := $(LIB)/monocypher
-COMPACT := $(LIB)/compact25519
-C25519 := $(COMPACT)/c25519
-JSMN := $(LIB)/JSMN
+JSMN := $(LIB)/jsmn
HTTP_CURL_FILE = $(MICROSUI_CORE)/impl/http/http_curl.c # This Makefile needs cURL installed in the system
HTTP_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/http/http_unsupported.c # This file is used when make is made on a system without cURL support
@@ -17,16 +15,14 @@ HTTP_LIBS = -lcurl $(if $(filter Windows_NT,$(OS)),-lws2_32 -lbcrypt -lwldap32 -
WIFI_DESKTOP_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_desktop.c
WIFI_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_unsupported.c # This file is used when make is made on a system without WiFi support
-CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(COMPACT) -I$(C25519) -I$(JSMN)
+CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(JSMN)
SOURCES := encode_conversions.c \
- $(SRC)/*.c \
- $(MICROSUI_CORE)/*.c \
- $(UTILS)/*.c \
- $(JSMN)/*.c \
+ $(wildcard $(SRC)/*.c) \
+ $(wildcard $(MICROSUI_CORE)/*.c) \
+ $(wildcard $(UTILS)/*.c) \
+ $(wildcard $(JSMN)/*.c) \
$(wildcard $(MONOCYPHER)/*.c) \
- $(wildcard $(COMPACT)/*.c) \
- $(wildcard $(C25519)/*.c) \
$(HTTP_CURL_FILE) \
$(HTTP_UNSUPPORTED_FILE) \
$(WIFI_DESKTOP_FILE) \
diff --git a/examples/core_examples/encode_conversions/encode_conversions.c b/examples/core_examples/encode_conversions/encode_conversions.c
index 2e26741..876d96e 100644
--- a/examples/core_examples/encode_conversions/encode_conversions.c
+++ b/examples/core_examples/encode_conversions/encode_conversions.c
@@ -1,8 +1,8 @@
#include
#include
#include
-#include "microsui/byte_conversions.h"
+#include "MicroSui.h"
int main() {
printf("\t\t Byte / HEXA and BASE64 CONVERSION examples:\n");
diff --git a/examples/core_examples/encode_decode_privkey/Makefile b/examples/core_examples/encode_decode_privkey/Makefile
index 1f83f4f..f1407f3 100644
--- a/examples/core_examples/encode_decode_privkey/Makefile
+++ b/examples/core_examples/encode_decode_privkey/Makefile
@@ -6,9 +6,7 @@ UTILS := $(MICROSUI_CORE)/utils
LIB := $(MICROSUI_CORE)/lib
MONOCYPHER := $(LIB)/monocypher
-COMPACT := $(LIB)/compact25519
-C25519 := $(COMPACT)/c25519
-JSMN := $(LIB)/JSMN
+JSMN := $(LIB)/jsmn
HTTP_CURL_FILE = $(MICROSUI_CORE)/impl/http/http_curl.c # This Makefile needs cURL installed in the system
HTTP_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/http/http_unsupported.c # This file is used when make is made on a system without cURL support
@@ -17,16 +15,14 @@ HTTP_LIBS = -lcurl $(if $(filter Windows_NT,$(OS)),-lws2_32 -lbcrypt -lwldap32 -
WIFI_DESKTOP_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_desktop.c
WIFI_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_unsupported.c # This file is used when make is made on a system without WiFi support
-CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(COMPACT) -I$(C25519) -I$(JSMN)
+CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(JSMN)
SOURCES := encode_decode_privkey.c \
- $(SRC)/*.c \
- $(MICROSUI_CORE)/*.c \
- $(UTILS)/*.c \
- $(JSMN)/*.c \
+ $(wildcard $(SRC)/*.c) \
+ $(wildcard $(MICROSUI_CORE)/*.c) \
+ $(wildcard $(UTILS)/*.c) \
+ $(wildcard $(JSMN)/*.c) \
$(wildcard $(MONOCYPHER)/*.c) \
- $(wildcard $(COMPACT)/*.c) \
- $(wildcard $(C25519)/*.c) \
$(HTTP_CURL_FILE) \
$(HTTP_UNSUPPORTED_FILE) \
$(WIFI_DESKTOP_FILE) \
diff --git a/examples/core_examples/encode_decode_privkey/encode_decode_privkey.c b/examples/core_examples/encode_decode_privkey/encode_decode_privkey.c
index 3df7420..e359033 100644
--- a/examples/core_examples/encode_decode_privkey/encode_decode_privkey.c
+++ b/examples/core_examples/encode_decode_privkey/encode_decode_privkey.c
@@ -1,7 +1,8 @@
#include
#include
#include
-#include "microsui/cryptography.h"
+
+#include "MicroSui.h"
const char *private_key_1_bech32 = "suiprivkey1qqqsyqcyq5rqwzqfpg9scrgwpugpzysnzs23v9ccrydpk8qarc0jqa4ffsr";
@@ -17,7 +18,7 @@ int main() {
printf("\t1 - decode_sui_privkey:\n");
uint8_t private_key_output[32];
- if (microsui_decode_sui_privkey(private_key_1_bech32, private_key_output) == 0) {
+ if (microsui_decode_bech32_private_key(private_key_output, private_key_1_bech32) == 0) {
printf("Original Bech32 Key: %s\n", private_key_1_bech32);
printf("Decoded Key: ");
for (int i = 0; i < 32; i++) {
@@ -30,7 +31,7 @@ int main() {
printf("\n\n\t2 - encode_sui_privkey:\n");
char private_key_bech32_output[71];
- if (microsui_encode_sui_privkey(private_key_2, private_key_bech32_output) == 0) {
+ if (microsui_encode_bech32_private_key(private_key_bech32_output, private_key_2) == 0) {
printf("Original Hexa Key: ");
for (int i = 0; i < 32; i++) {
printf("%02x", private_key_2[i]);
diff --git a/examples/core_examples/offline_sign/Makefile b/examples/core_examples/offline_sign/Makefile
index 59269aa..56329d1 100644
--- a/examples/core_examples/offline_sign/Makefile
+++ b/examples/core_examples/offline_sign/Makefile
@@ -6,9 +6,7 @@ UTILS := $(MICROSUI_CORE)/utils
LIB := $(MICROSUI_CORE)/lib
MONOCYPHER := $(LIB)/monocypher
-COMPACT := $(LIB)/compact25519
-C25519 := $(COMPACT)/c25519
-JSMN := $(LIB)/JSMN
+JSMN := $(LIB)/jsmn
HTTP_CURL_FILE = $(MICROSUI_CORE)/impl/http/http_curl.c # This Makefile needs cURL installed in the system
HTTP_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/http/http_unsupported.c # This file is used when make is made on a system without cURL support
@@ -17,16 +15,14 @@ HTTP_LIBS = -lcurl $(if $(filter Windows_NT,$(OS)),-lws2_32 -lbcrypt -lwldap32 -
WIFI_DESKTOP_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_desktop.c
WIFI_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_unsupported.c # This file is used when make is made on a system without WiFi support
-CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(COMPACT) -I$(C25519) -I$(JSMN)
+CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(JSMN)
SOURCES := offline_sign.c \
- $(SRC)/*.c \
- $(MICROSUI_CORE)/*.c \
- $(UTILS)/*.c \
- $(JSMN)/*.c \
+ $(wildcard $(SRC)/*.c) \
+ $(wildcard $(MICROSUI_CORE)/*.c) \
+ $(wildcard $(UTILS)/*.c) \
+ $(wildcard $(JSMN)/*.c) \
$(wildcard $(MONOCYPHER)/*.c) \
- $(wildcard $(COMPACT)/*.c) \
- $(wildcard $(C25519)/*.c) \
$(HTTP_CURL_FILE) \
$(HTTP_UNSUPPORTED_FILE) \
$(WIFI_DESKTOP_FILE) \
diff --git a/examples/core_examples/offline_sign/offline_sign.c b/examples/core_examples/offline_sign/offline_sign.c
index 776915d..f63cf9e 100644
--- a/examples/core_examples/offline_sign/offline_sign.c
+++ b/examples/core_examples/offline_sign/offline_sign.c
@@ -1,14 +1,14 @@
#include
#include
#include
-#include "microsui/sign.h"
-#include "microsui/byte_conversions.h"
+
+#include "MicroSui.h"
// Sui Message in hex format (this message must be signed)
const char* message_hex = "00000200080065cd1d0000000000202e3d52393c9035afd1ef38abd7fce2dad71f0e276b522fb274f4e14d1df974720202000101000001010300000000010100d79a4c7a655aa80cf92069bbac9666705f1d7181ff9c2d59efbc7e6ec4c3379d0180dc491e55e7caabfcdd1b0f538928d8d54107b9c1def3ed0baa3aa5106ba8674f0dd01400000000204b7e9da00f30cd1edf4d40710213c15a862e1fc175f2edb2b2c870c8559d65cdd79a4c7a655aa80cf92069bbac9666705f1d7181ff9c2d59efbc7e6ec4c3379de80300000000000040ab3c000000000000";
-// You must place your PK (in bytes format) here.
-const uint8_t private_key[32] = {
+// You must place your seed private key / secret key (in bytes format) here.
+const uint8_t private_key_seed[32] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -16,7 +16,7 @@ const uint8_t private_key[32] = {
};
int main() {
- printf("\n\t\t\t --- SUI OFFLINE SIGN DEMO ---\n");
+ printf("\n\t\t\t --- Microsui - Sui OFFLINE Signature ---\n");
printf("\n\tOriginal Message: %s", message_hex);
// Converting the message from hex to bytes
@@ -24,10 +24,10 @@ int main() {
uint8_t message[message_len];
hex_to_bytes(message_hex, message, message_len);
- // Generating the Sui Signature from the message and private key (private_key is in constant.h)
+ // Generating the Sui Signature from the message and private key
uint8_t sui_sig[97];
printf("\n\n\n Generating Signature...\n");
- microsui_sign_ed25519(sui_sig, message, message_len, private_key);
+ microsui_sign_ed25519(sui_sig, message, message_len, private_key_seed);
printf("\t Signature created successfully\n");
// Verifying the Sui Signature
diff --git a/examples/core_examples/offline_sign_with_bech32_privkey/Makefile b/examples/core_examples/offline_sign_with_bech32_privkey/Makefile
index 73cfcfe..91ad073 100644
--- a/examples/core_examples/offline_sign_with_bech32_privkey/Makefile
+++ b/examples/core_examples/offline_sign_with_bech32_privkey/Makefile
@@ -6,9 +6,7 @@ UTILS := $(MICROSUI_CORE)/utils
LIB := $(MICROSUI_CORE)/lib
MONOCYPHER := $(LIB)/monocypher
-COMPACT := $(LIB)/compact25519
-C25519 := $(COMPACT)/c25519
-JSMN := $(LIB)/JSMN
+JSMN := $(LIB)/jsmn
HTTP_CURL_FILE = $(MICROSUI_CORE)/impl/http/http_curl.c # This Makefile needs cURL installed in the system
HTTP_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/http/http_unsupported.c # This file is used when make is made on a system without cURL support
@@ -17,16 +15,14 @@ HTTP_LIBS = -lcurl $(if $(filter Windows_NT,$(OS)),-lws2_32 -lbcrypt -lwldap32 -
WIFI_DESKTOP_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_desktop.c
WIFI_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_unsupported.c # This file is used when make is made on a system without WiFi support
-CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(COMPACT) -I$(C25519) -I$(JSMN)
+CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(JSMN)
SOURCES := offline_sign_with_bech32_privkey.c \
- $(SRC)/*.c \
- $(MICROSUI_CORE)/*.c \
- $(UTILS)/*.c \
- $(JSMN)/*.c \
+ $(wildcard $(SRC)/*.c) \
+ $(wildcard $(MICROSUI_CORE)/*.c) \
+ $(wildcard $(UTILS)/*.c) \
+ $(wildcard $(JSMN)/*.c) \
$(wildcard $(MONOCYPHER)/*.c) \
- $(wildcard $(COMPACT)/*.c) \
- $(wildcard $(C25519)/*.c) \
$(HTTP_CURL_FILE) \
$(HTTP_UNSUPPORTED_FILE) \
$(WIFI_DESKTOP_FILE) \
diff --git a/examples/core_examples/offline_sign_with_bech32_privkey/offline_sign_with_bech32_privkey.c b/examples/core_examples/offline_sign_with_bech32_privkey/offline_sign_with_bech32_privkey.c
index 3e800ed..1e4c2c5 100644
--- a/examples/core_examples/offline_sign_with_bech32_privkey/offline_sign_with_bech32_privkey.c
+++ b/examples/core_examples/offline_sign_with_bech32_privkey/offline_sign_with_bech32_privkey.c
@@ -1,9 +1,8 @@
#include
#include
#include
-#include "microsui/sign.h"
-#include "microsui/cryptography.h"
-#include "microsui/byte_conversions.h"
+
+#include "MicroSui.h"
// Sui Message in hex format (this message must be signed)
const char* message_hex = "00000200080065cd1d0000000000202e3d52393c9035afd1ef38abd7fce2dad71f0e276b522fb274f4e14d1df974720202000101000001010300000000010100d79a4c7a655aa80cf92069bbac9666705f1d7181ff9c2d59efbc7e6ec4c3379d0180dc491e55e7caabfcdd1b0f538928d8d54107b9c1def3ed0baa3aa5106ba8674f0dd01400000000204b7e9da00f30cd1edf4d40710213c15a862e1fc175f2edb2b2c870c8559d65cdd79a4c7a655aa80cf92069bbac9666705f1d7181ff9c2d59efbc7e6ec4c3379de80300000000000040ab3c000000000000";
@@ -11,14 +10,13 @@ const char* message_hex = "00000200080065cd1d0000000000202e3d52393c9035afd1ef38a
// You must place your bech32 private key here
const char *private_key_bech32 = "suiprivkey1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq509duq";
-
int main() {
- printf("\n\t\t\t --- SUI OFFLINE SIGN DEMO (with Bech32 Private Key) ---\n");
+ printf("\n\t\t\t --- Microsui - Sui OFFLINE Signature (with Bech32 Private Key) ---\n");
printf("\n\tOriginal Message: %s", message_hex);
// Decoding the Bech32 private key to bytes
uint8_t private_key[32];
- if (microsui_decode_sui_privkey(private_key_bech32, private_key) != 0) {
+ if (microsui_decode_bech32_private_key(private_key, private_key_bech32) != 0) {
printf("Invalid Bech32 private key.\n");
return -1;
}
diff --git a/examples/core_examples/prepare_and_send_transaction/Makefile b/examples/core_examples/prepare_and_send_transaction/Makefile
index 7e023bf..0af221c 100644
--- a/examples/core_examples/prepare_and_send_transaction/Makefile
+++ b/examples/core_examples/prepare_and_send_transaction/Makefile
@@ -6,9 +6,7 @@ UTILS := $(MICROSUI_CORE)/utils
LIB := $(MICROSUI_CORE)/lib
MONOCYPHER := $(LIB)/monocypher
-COMPACT := $(LIB)/compact25519
-C25519 := $(COMPACT)/c25519
-JSMN := $(LIB)/JSMN
+JSMN := $(LIB)/jsmn
HTTP_CURL_FILE = $(MICROSUI_CORE)/impl/http/http_curl.c # This Makefile needs cURL installed in the system
HTTP_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/http/http_unsupported.c # This file is used when make is made on a system without cURL support
@@ -17,16 +15,14 @@ HTTP_LIBS = -lcurl $(if $(filter Windows_NT,$(OS)),-lws2_32 -lbcrypt -lwldap32 -
WIFI_DESKTOP_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_desktop.c
WIFI_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_unsupported.c # This file is used when make is made on a system without WiFi support
-CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(COMPACT) -I$(C25519) -I$(JSMN)
+CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(JSMN)
SOURCES := prepare_and_send_transaction.c \
- $(SRC)/*.c \
- $(MICROSUI_CORE)/*.c \
- $(UTILS)/*.c \
- $(JSMN)/*.c \
+ $(wildcard $(SRC)/*.c) \
+ $(wildcard $(MICROSUI_CORE)/*.c) \
+ $(wildcard $(UTILS)/*.c) \
+ $(wildcard $(JSMN)/*.c) \
$(wildcard $(MONOCYPHER)/*.c) \
- $(wildcard $(COMPACT)/*.c) \
- $(wildcard $(C25519)/*.c) \
$(HTTP_CURL_FILE) \
$(HTTP_UNSUPPORTED_FILE) \
$(WIFI_DESKTOP_FILE) \
diff --git a/examples/core_examples/prepare_and_send_transaction/prepare_and_send_transaction.c b/examples/core_examples/prepare_and_send_transaction/prepare_and_send_transaction.c
index 17a5e7f..cf9afbc 100644
--- a/examples/core_examples/prepare_and_send_transaction/prepare_and_send_transaction.c
+++ b/examples/core_examples/prepare_and_send_transaction/prepare_and_send_transaction.c
@@ -2,9 +2,8 @@
#include
#include
#include
-#include "microsui/byte_conversions.h"
-#include "microsui/rpc_json_builder.h"
-#include "microsui/http_router.h"
+
+#include "MicroSui.h"
// Sui Message and Signature in hex format
const char* sui_message = "0000020008c0320a030000000000202e3d52393c9035afd1ef38abd7fce2dad71f0e276b522fb274f4e14d1df974720202000101000001010300000000010100d79a4c7a655aa80cf92069bbac9666705f1d7181ff9c2d59efbc7e6ec4c3379d0115bc7e3113dfaebc7bdb30676e56e6ff651365235b74a202cbb1e73f57eaeb78600fd0140000000020c00463b22a32bebcb028b264d61bfa963c3f6a82bd7487c52bec8b2bf0c0e373d79a4c7a655aa80cf92069bbac9666705f1d7181ff9c2d59efbc7e6ec4c3379de80300000000000040ab3c000000000000";
diff --git a/examples/core_examples/verify_signatures/Makefile b/examples/core_examples/verify_signatures/Makefile
new file mode 100644
index 0000000..5ebd888
--- /dev/null
+++ b/examples/core_examples/verify_signatures/Makefile
@@ -0,0 +1,47 @@
+ROOT_DIR := ../../..
+SRC := $(ROOT_DIR)/src
+INCLUDE := $(ROOT_DIR)/include
+MICROSUI_CORE := $(ROOT_DIR)/src/microsui_core
+UTILS := $(MICROSUI_CORE)/utils
+LIB := $(MICROSUI_CORE)/lib
+
+MONOCYPHER := $(LIB)/monocypher
+JSMN := $(LIB)/jsmn
+
+HTTP_CURL_FILE = $(MICROSUI_CORE)/impl/http/http_curl.c # This Makefile needs cURL installed in the system
+HTTP_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/http/http_unsupported.c # This file is used when make is made on a system without cURL support
+HTTP_LIBS = -lcurl $(if $(filter Windows_NT,$(OS)),-lws2_32 -lbcrypt -lwldap32 -lcrypt32)
+
+WIFI_DESKTOP_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_desktop.c
+WIFI_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_unsupported.c # This file is used when make is made on a system without WiFi support
+
+CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(JSMN)
+
+SOURCES := verify_signatures.c \
+ $(wildcard $(SRC)/*.c) \
+ $(wildcard $(MICROSUI_CORE)/*.c) \
+ $(wildcard $(UTILS)/*.c) \
+ $(wildcard $(JSMN)/*.c) \
+ $(wildcard $(MONOCYPHER)/*.c) \
+ $(HTTP_CURL_FILE) \
+ $(HTTP_UNSUPPORTED_FILE) \
+ $(WIFI_DESKTOP_FILE) \
+ $(WIFI_UNSUPPORTED_FILE)
+
+OUTPUT := verify_signatures.out
+
+all: clean_before_build $(OUTPUT)
+
+$(OUTPUT): $(SOURCES)
+ @echo "Compiling example: $@"
+ gcc $(CFLAGS) $^ -o $@ $(HTTP_LIBS)
+
+.PHONY: clean clean_before_build
+
+clean_before_build:
+ @echo "Cleaning old binary if it exists..."
+ @rm -f $(OUTPUT)
+
+clean:
+ @echo "Removing binary..."
+ @rm -f $(OUTPUT)
\ No newline at end of file
diff --git a/examples/core_examples/verify_signatures/verify_signatures.c b/examples/core_examples/verify_signatures/verify_signatures.c
new file mode 100644
index 0000000..8b6755e
--- /dev/null
+++ b/examples/core_examples/verify_signatures/verify_signatures.c
@@ -0,0 +1,56 @@
+#include
+#include
+#include
+
+#include "MicroSui.h"
+
+// Sui Message in hex format (this message must be signed)
+const char* message_hex = "00000200080065cd1d0000000000202e3d52393c9035afd1ef38abd7fce2dad71f0e276b522fb274f4e14d1df974720202000101000001010300000000010100d79a4c7a655aa80cf92069bbac9666705f1d7181ff9c2d59efbc7e6ec4c3379d0180dc491e55e7caabfcdd1b0f538928d8d54107b9c1def3ed0baa3aa5106ba8674f0dd01400000000204b7e9da00f30cd1edf4d40710213c15a862e1fc175f2edb2b2c870c8559d65cdd79a4c7a655aa80cf92069bbac9666705f1d7181ff9c2d59efbc7e6ec4c3379de80300000000000040ab3c000000000000";
+
+// You must place your seed private key / secret key (in bytes format) here.
+const uint8_t private_key_seed[32] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+int main() {
+ printf("\n\t\t\t --- Sui Signature Verification ---\n");
+ printf("\n\tOriginal Message: %s", message_hex);
+
+ // Converting the message from hex to bytes
+ size_t message_len = strlen(message_hex) / 2; // 2 hex chars = 1 byte
+ uint8_t message[message_len];
+ hex_to_bytes(message_hex, message, message_len);
+
+ // Generating the Sui Signature from the message and private key
+ uint8_t sui_sig[97];
+ printf("\n\n\n Generating Signature...\n");
+ microsui_sign_ed25519(sui_sig, message, message_len, private_key_seed);
+ printf("\t Signature created successfully\n\n");
+
+ // Verifying the Sui Signature
+ int verification_result = microsui_verify_signature(sui_sig, message, message_len);
+ if(verification_result == 0) {
+ printf("\t 1 - Signature verified successfully\n");
+ } else {
+ printf("\t Signature verification failed\n");
+ printf("\t Error code: %d\n\n", verification_result);
+ }
+
+ // Veryfing the Sui Signature with the expected public key (derived from the seed private key)
+ uint8_t public_key[32];
+ microsui_derive_public_key_ed25519(public_key, private_key_seed);
+ verification_result = microsui_verify_signature_ed25519_with_public_key(sui_sig, message, message_len, public_key);
+ if(verification_result == 0) {
+ printf("\t 2 - Signature verified successfully with public key validation\n");
+ } else {
+ printf("\t Signature verification with public key validation failed\n");
+ printf("\t Error code: %d\n\n", verification_result);
+ }
+
+ printf("\n\t SIGNATURE must be sended to the Gateway to be broadcasted to the Sui Network...\n");
+
+ return 0;
+}
\ No newline at end of file
diff --git a/examples/sdk_examples/client_demo/Makefile b/examples/sdk_examples/client_demo/Makefile
index 17bb2f0..8e6bcb7 100644
--- a/examples/sdk_examples/client_demo/Makefile
+++ b/examples/sdk_examples/client_demo/Makefile
@@ -6,9 +6,7 @@ UTILS := $(MICROSUI_CORE)/utils
LIB := $(MICROSUI_CORE)/lib
MONOCYPHER := $(LIB)/monocypher
-COMPACT := $(LIB)/compact25519
-C25519 := $(COMPACT)/c25519
-JSMN := $(LIB)/JSMN
+JSMN := $(LIB)/jsmn
HTTP_CURL_FILE = $(MICROSUI_CORE)/impl/http/http_curl.c # This Makefile needs cURL installed in the system
HTTP_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/http/http_unsupported.c # This file is used when make is made on a system without cURL support
@@ -17,16 +15,14 @@ HTTP_LIBS = -lcurl $(if $(filter Windows_NT,$(OS)),-lws2_32 -lbcrypt -lwldap32 -
WIFI_DESKTOP_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_desktop.c
WIFI_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_unsupported.c # This file is used when make is made on a system without WiFi support
-CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(COMPACT) -I$(C25519) -I$(JSMN)
+CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(JSMN)
SOURCES := client_demo.c \
- $(SRC)/*.c \
- $(MICROSUI_CORE)/*.c \
- $(UTILS)/*.c \
- $(JSMN)/*.c \
+ $(wildcard $(SRC)/*.c) \
+ $(wildcard $(MICROSUI_CORE)/*.c) \
+ $(wildcard $(UTILS)/*.c) \
+ $(wildcard $(JSMN)/*.c) \
$(wildcard $(MONOCYPHER)/*.c) \
- $(wildcard $(COMPACT)/*.c) \
- $(wildcard $(C25519)/*.c) \
$(HTTP_CURL_FILE) \
$(HTTP_UNSUPPORTED_FILE) \
$(WIFI_DESKTOP_FILE) \
diff --git a/examples/sdk_examples/keypair_demo/Makefile b/examples/sdk_examples/keypair_demo/Makefile
index 59e74ef..3c85a26 100644
--- a/examples/sdk_examples/keypair_demo/Makefile
+++ b/examples/sdk_examples/keypair_demo/Makefile
@@ -6,9 +6,7 @@ UTILS := $(MICROSUI_CORE)/utils
LIB := $(MICROSUI_CORE)/lib
MONOCYPHER := $(LIB)/monocypher
-COMPACT := $(LIB)/compact25519
-C25519 := $(COMPACT)/c25519
-JSMN := $(LIB)/JSMN
+JSMN := $(LIB)/jsmn
HTTP_CURL_FILE = $(MICROSUI_CORE)/impl/http/http_curl.c # This Makefile needs cURL installed in the system
HTTP_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/http/http_unsupported.c # This file is used when make is made on a system without cURL support
@@ -17,16 +15,14 @@ HTTP_LIBS = -lcurl $(if $(filter Windows_NT,$(OS)),-lws2_32 -lbcrypt -lwldap32 -
WIFI_DESKTOP_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_desktop.c
WIFI_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_unsupported.c # This file is used when make is made on a system without WiFi support
-CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(COMPACT) -I$(C25519) -I$(JSMN)
+CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(JSMN)
SOURCES := keypair_demo.c \
- $(SRC)/*.c \
- $(MICROSUI_CORE)/*.c \
- $(UTILS)/*.c \
- $(JSMN)/*.c \
+ $(wildcard $(SRC)/*.c) \
+ $(wildcard $(MICROSUI_CORE)/*.c) \
+ $(wildcard $(UTILS)/*.c) \
+ $(wildcard $(JSMN)/*.c) \
$(wildcard $(MONOCYPHER)/*.c) \
- $(wildcard $(COMPACT)/*.c) \
- $(wildcard $(C25519)/*.c) \
$(HTTP_CURL_FILE) \
$(HTTP_UNSUPPORTED_FILE) \
$(WIFI_DESKTOP_FILE) \
diff --git a/examples/sdk_examples/transaction_demo/Makefile b/examples/sdk_examples/transaction_demo/Makefile
index 57e6b1a..f0fac57 100644
--- a/examples/sdk_examples/transaction_demo/Makefile
+++ b/examples/sdk_examples/transaction_demo/Makefile
@@ -6,9 +6,7 @@ UTILS := $(MICROSUI_CORE)/utils
LIB := $(MICROSUI_CORE)/lib
MONOCYPHER := $(LIB)/monocypher
-COMPACT := $(LIB)/compact25519
-C25519 := $(COMPACT)/c25519
-JSMN := $(LIB)/JSMN
+JSMN := $(LIB)/jsmn
HTTP_CURL_FILE = $(MICROSUI_CORE)/impl/http/http_curl.c # This Makefile needs cURL installed in the system
HTTP_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/http/http_unsupported.c # This file is used when make is made on a system without cURL support
@@ -17,16 +15,14 @@ HTTP_LIBS = -lcurl $(if $(filter Windows_NT,$(OS)),-lws2_32 -lbcrypt -lwldap32 -
WIFI_DESKTOP_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_desktop.c
WIFI_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_unsupported.c # This file is used when make is made on a system without WiFi support
-CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(COMPACT) -I$(C25519) -I$(JSMN)
+CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(JSMN)
SOURCES := transaction_demo.c \
- $(SRC)/*.c \
- $(MICROSUI_CORE)/*.c \
- $(UTILS)/*.c \
- $(JSMN)/*.c \
+ $(wildcard $(SRC)/*.c) \
+ $(wildcard $(MICROSUI_CORE)/*.c) \
+ $(wildcard $(UTILS)/*.c) \
+ $(wildcard $(JSMN)/*.c) \
$(wildcard $(MONOCYPHER)/*.c) \
- $(wildcard $(COMPACT)/*.c) \
- $(wildcard $(C25519)/*.c) \
$(HTTP_CURL_FILE) \
$(HTTP_UNSUPPORTED_FILE) \
$(WIFI_DESKTOP_FILE) \
diff --git a/examples/sdk_examples/validating_signature/Makefile b/examples/sdk_examples/validating_signature/Makefile
index 7952c18..c51d40b 100644
--- a/examples/sdk_examples/validating_signature/Makefile
+++ b/examples/sdk_examples/validating_signature/Makefile
@@ -6,9 +6,7 @@ UTILS := $(MICROSUI_CORE)/utils
LIB := $(MICROSUI_CORE)/lib
MONOCYPHER := $(LIB)/monocypher
-COMPACT := $(LIB)/compact25519
-C25519 := $(COMPACT)/c25519
-JSMN := $(LIB)/JSMN
+JSMN := $(LIB)/jsmn
HTTP_CURL_FILE = $(MICROSUI_CORE)/impl/http/http_curl.c # This Makefile needs cURL installed in the system
HTTP_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/http/http_unsupported.c # This file is used when make is made on a system without cURL support
@@ -17,16 +15,14 @@ HTTP_LIBS = -lcurl $(if $(filter Windows_NT,$(OS)),-lws2_32 -lbcrypt -lwldap32 -
WIFI_DESKTOP_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_desktop.c
WIFI_UNSUPPORTED_FILE = $(MICROSUI_CORE)/impl/wifi/wifi_unsupported.c # This file is used when make is made on a system without WiFi support
-CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(COMPACT) -I$(C25519) -I$(JSMN)
+CFLAGS := -Wall -Wextra -I$(INCLUDE) -I$(SRC) -I$(MICROSUI_CORE) -I$(UTILS) -I$(LIB) -I$(MONOCYPHER) -I$(JSMN)
SOURCES := validating_signature.c \
- $(SRC)/*.c \
- $(MICROSUI_CORE)/*.c \
- $(UTILS)/*.c \
- $(JSMN)/*.c \
+ $(wildcard $(SRC)/*.c) \
+ $(wildcard $(MICROSUI_CORE)/*.c) \
+ $(wildcard $(UTILS)/*.c) \
+ $(wildcard $(JSMN)/*.c) \
$(wildcard $(MONOCYPHER)/*.c) \
- $(wildcard $(COMPACT)/*.c) \
- $(wildcard $(C25519)/*.c) \
$(HTTP_CURL_FILE) \
$(HTTP_UNSUPPORTED_FILE) \
$(WIFI_DESKTOP_FILE) \
diff --git a/examples/sdk_examples/validating_signature/validating_signature.c b/examples/sdk_examples/validating_signature/validating_signature.c
index 9bdf649..6531731 100644
--- a/examples/sdk_examples/validating_signature/validating_signature.c
+++ b/examples/sdk_examples/validating_signature/validating_signature.c
@@ -37,7 +37,7 @@ int main(void) {
printf("\t - Signature Verification is CORRECT for Message 1 -- OK\n");
// Validation with message 2 (incorrect)
int verification_result_2 = microsui_verify_signature(sig.bytes, tx2.tx_bytes.data, tx2.tx_bytes.length);
- if(verification_result_2 == -1)
+ if(verification_result_2 != 0)
printf("\t - Signature Verification is FAILED for Message 2 -- OK\n");
printf("\n\n\t\t --- END OF TRANSACTION DEMO ---\n");
diff --git a/library.json b/library.json
index 9cb5bb3..136a198 100644
--- a/library.json
+++ b/library.json
@@ -1,6 +1,6 @@
{
"name": "microsui-lib",
- "version": "0.3.2",
+ "version": "0.3.3",
"description": "MicroSui Library is a lightweight C library for embedded systems to interact with the Sui Network Blockchain",
"keywords": "microsui, sui, blockchain, sui-network, walrus, cryptography, c-library",
"repository": {
@@ -22,9 +22,7 @@
"srcDir": "src",
"includeDir": "include",
"flags": [
- "-Isrc/microsui_core/lib/monocypher",
- "-Isrc/microsui_core/lib/compact25519",
- "-Isrc/microsui_core/lib/compact25519/c25519"
+ "-Isrc/microsui_core/lib/monocypher"
],
"srcFilter": [
"+<*.c>",
@@ -32,8 +30,6 @@
"+",
"+",
"+",
- "+",
- "+",
"+",
"-",
"-",
diff --git a/library.properties b/library.properties
index 70138fc..76cd5f4 100644
--- a/library.properties
+++ b/library.properties
@@ -1,5 +1,5 @@
name=MicroSui
-version=0.3.2
+version=0.3.3
author=Gustavo Belbruno
maintainer=Gustavo Belbruno
sentence=Pure C library for interacting with the Sui Network blockchain from microcontrollers.
diff --git a/src/Keypair.c b/src/Keypair.c
index 3139c28..325617c 100644
--- a/src/Keypair.c
+++ b/src/Keypair.c
@@ -8,7 +8,8 @@
*
* Features:
* - Generate random keypairs from entropy.
- * - Initialize a keypair from a Bech32-encoded secret key string.
+ * - Initialize a keypair from a Sui Bech32-encoded private key string (also called
+ * "Secret Key" in the Mysten Labs TypeScript SDK).
* - Sign transaction messages with Ed25519.
* - Retrieve the secret key (Bech32), public key (raw bytes), and
* derive the Sui-formatted address.
@@ -17,7 +18,10 @@
* - Functions returning strings or buffers use static internal storage.
* Results will be overwritten by subsequent calls and are not thread-safe.
* - All cryptographic primitives are delegated to the MicroSui core modules.
- *
+ * - Mysten Labs' TypeScript SDK uses the term "Secret Key" for the Sui Bech32 encoded
+ * private key string. To maintain consistency with the TypeScript SDK, the naming
+ * convention "Secret Key" is used here regarding the Sui Bech32-encoded private key.
+ *
* Inspired by the Mysten Labs TypeScript SDK, adapted for embedded C.
*/
@@ -48,7 +52,7 @@ typedef struct {
typedef struct MicroSuiEd25519 MicroSuiEd25519;
struct MicroSuiEd25519 {
- uint8_t secret_key[32];
+ uint8_t seed[32];
// OO-style methods
SuiSignature (*signTransaction)(MicroSuiEd25519 *self, const char *msg);
@@ -60,7 +64,7 @@ struct MicroSuiEd25519 {
// ==========================
// Constructor prototypes
// ==========================
-MicroSuiEd25519 SuiKeypair_generate(uint8_t seed_extra);
+MicroSuiEd25519 SuiKeypair_generate(uint8_t rng_entropy);
MicroSuiEd25519 SuiKeypair_fromSecretKey(const char *sk);
// ==========================
@@ -82,19 +86,21 @@ static const char* ms_toSuiAddress_impl(MicroSuiEd25519 *self);
* Function pointers for signing, retrieving keys, and deriving the
* Sui address are also assigned.
*
- * @param[in] seed_extra Extra seed mixed with current time to initialize PRNG.
+ * @param[in] rng_entropy High-quality entropy from hardware (ADC noise,
+ * temperature jitter, etc.) or very high-quality software entropy.
+ * Should NOT be predictable.
*
* @return Initialized MicroSuiEd25519 struct.
*/
-MicroSuiEd25519 SuiKeypair_generate(uint8_t seed_extra) {
+MicroSuiEd25519 SuiKeypair_generate(uint8_t rng_entropy) {
MicroSuiEd25519 kp;
memset(&kp, 0, sizeof(kp));
// Generate a random secret key
- unsigned seed = (unsigned)time(NULL) ^ seed_extra;
- srand(seed);
+ unsigned rng = (unsigned)time(NULL) ^ rng_entropy;
+ srand(rng);
for (size_t i = 0; i < 32; i++) {
- kp.secret_key[i] = (uint8_t)(rand() % 256);
+ kp.seed[i] = (uint8_t)(rand() % 256);
}
// Assign methods
@@ -117,6 +123,10 @@ MicroSuiEd25519 SuiKeypair_generate(uint8_t seed_extra) {
* @param[in] sk Bech32-encoded secret key string.
*
* @return Initialized MicroSuiEd25519 struct, or empty if decoding fails.
+ *
+ * @note Mysten Labs' TypeScript SDK uses the term "Secret Key" for the Sui Bech32
+ * encoded private key string. To maintain consistency with the TypeScript SDK,
+ * the naming convention `fromSecretKey` is used here.
*/
MicroSuiEd25519 SuiKeypair_fromSecretKey(const char *sk) {
MicroSuiEd25519 kp;
@@ -125,7 +135,7 @@ MicroSuiEd25519 SuiKeypair_fromSecretKey(const char *sk) {
if (sk == NULL || strlen(sk) == 0 || strlen(sk) != PK_BECH32_LEN) return kp; // Error: Invalid secret key: return empty struct
// Decode the secret key from Bech32
- if (microsui_decode_sui_privkey(sk, kp.secret_key) != 0) return kp; // Error: Decoding failed: return empty struct
+ if (microsui_decode_bech32_private_key(kp.seed, sk) != 0) return kp; // Error: Decoding failed: return empty struct
// Assign methods
kp.signTransaction = ms_signTransaction_impl;
@@ -159,7 +169,7 @@ static SuiSignature ms_signTransaction_impl(MicroSuiEd25519 *self, const char *m
hex_to_bytes(msg, message, message_len);
// sign
- microsui_sign_ed25519(sig.bytes, message, message_len, self->secret_key);
+ microsui_sign_ed25519(sig.bytes, message, message_len, self->seed);
// encode to base64
bytes_to_base64(sig.bytes, 97, sig.signature, sizeof(sig.signature));
@@ -177,10 +187,14 @@ static SuiSignature ms_signTransaction_impl(MicroSuiEd25519 *self, const char *m
* @param[in] self Pointer to MicroSuiEd25519 instance.
*
* @return Pointer to a static null-terminated string containing the secret key.
+ *
+ * @note Mysten Labs' TypeScript SDK returns the private key as a Sui Bech32 string
+ * with the name `Secret Key`. To maintain consistency with the TypeScript SDK,
+ * the naming convention `getSecretKey` is used here.
*/
static const char* ms_getSecretKey_impl(MicroSuiEd25519 *self) {
static char secret_key[PK_BECH32_LEN + 1]; // Placeholder for secret key
- microsui_encode_sui_privkey(self->secret_key, secret_key);
+ microsui_encode_bech32_private_key(secret_key, self->seed);
return secret_key; // placeholder
}
@@ -197,7 +211,7 @@ static const char* ms_getSecretKey_impl(MicroSuiEd25519 *self) {
*/
static const uint8_t* ms_getPublicKey_impl(MicroSuiEd25519 *self) {
static uint8_t public_key[32]; // Placeholder for Sui address
- get_public_key_from_private_key(self->secret_key, public_key);
+ microsui_derive_public_key_ed25519(public_key, self->seed);
return public_key; // placeholder
}
@@ -219,11 +233,11 @@ static const char* ms_toSuiAddress_impl(MicroSuiEd25519 *self) {
// Obtain the public key from the secret key
uint8_t public_key[32];
- get_public_key_from_private_key(self->secret_key, public_key);
+ microsui_derive_public_key_ed25519(public_key, self->seed);
// Encode public key to Sui address
uint8_t encoded_address[32];
- microsui_pubkey_to_sui_address(public_key, encoded_address);
+ microsui_derive_sui_address_ed25519(encoded_address, public_key);
// Convert the encoded address to a hex string
char encoded_address_string[65];
diff --git a/src/Keypair.h b/src/Keypair.h
index 8aa8bd1..2867ac2 100644
--- a/src/Keypair.h
+++ b/src/Keypair.h
@@ -21,7 +21,7 @@ typedef struct {
typedef struct MicroSuiEd25519 MicroSuiEd25519;
struct MicroSuiEd25519 {
- uint8_t secret_key[32];
+ uint8_t seed[32];
// OO-style methods
SuiSignature (*signTransaction)(MicroSuiEd25519 *self, const char *msg);
@@ -33,7 +33,7 @@ struct MicroSuiEd25519 {
// ==========================
// Constructors
// ==========================
-MicroSuiEd25519 SuiKeypair_generate(uint8_t seed_extra);
+MicroSuiEd25519 SuiKeypair_generate(uint8_t rng_entropy);
MicroSuiEd25519 SuiKeypair_fromSecretKey(const char *sk);
#endif // MICROSUI_KEYPAIR_H
\ No newline at end of file
diff --git a/src/microsui_core/cryptography.c b/src/microsui_core/cryptography.c
index b5db61b..32306d1 100644
--- a/src/microsui_core/cryptography.c
+++ b/src/microsui_core/cryptography.c
@@ -3,10 +3,10 @@
#include
#include
#include
+#include "lib/monocypher/monocypher.h"
#include "cryptography.h"
-
static const char ALPHABET[] = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
static const int8_t ALPHABET_MAP[128] = {
@@ -103,14 +103,13 @@ static void bech32_create_checksum(const char *hrp, const uint8_t *data, size_t
}
/**
- * @brief Decode a Sui Bech32 private key string into 32 raw bytes.
+ * @brief Decode a Sui Bech32 private key string into 32 raw seed bytes.
*
* Validates the Bech32-encoded private key (HRP = "suiprivkey", no mixed case),
- * converts the 5-bit words back to 8-bit bytes, and extracts the 32-byte secret
- * (sk) after the 1-byte scheme flag.
+ * converts the 5-bit words back to 8-bit bytes, and extracts the 32-byte seed after the 1-byte scheme flag.
*
- * @param[in] privkey_bech Null-terminated Bech32 string ("suiprivkey1...").
- * @param[out] privkey_bytes_output Output buffer for the 32-byte secret key.
+ * @param[out] seed_out Output buffer for the 32-byte seed private key.
+ * @param[in] private_key_bech Null-terminated Bech32 private key string ("suiprivkey1...").
*
* @return 0 on success; -1 on invalid length/format, mixed case, bad alphabet,
* conversion failure, or unexpected payload size.
@@ -118,13 +117,13 @@ static void bech32_create_checksum(const char *hrp, const uint8_t *data, size_t
* @note Expects total string length == PK_BECH32_LEN. Mixed case is rejected.
* @note The returned key is the 32-byte seed; callers must handle it securely.
*/
-int microsui_decode_sui_privkey(const char *privkey_bech, uint8_t privkey_bytes_output[32]) {
- size_t len = strlen(privkey_bech);
+int microsui_decode_bech32_private_key(uint8_t seed_out[32], const char *private_key_bech) {
+ size_t len = strlen(private_key_bech);
if (len != PK_BECH32_LEN) return -1;
bool hasLower = false, hasUpper = false;
for (size_t i = 0; i < len; i++) {
- char c = privkey_bech[i];
+ char c = private_key_bech[i];
if (c >= 'a' && c <= 'z') hasLower = true;
if (c >= 'A' && c <= 'Z') hasUpper = true;
}
@@ -132,7 +131,7 @@ int microsui_decode_sui_privkey(const char *privkey_bech, uint8_t privkey_bytes_
char str[PK_BECH32_LEN + 1];
for (size_t i = 0; i < len; i++) {
- str[i] = TOLOWER(privkey_bech[i]);
+ str[i] = TOLOWER(private_key_bech[i]);
}
str[len] = '\0';
@@ -169,34 +168,42 @@ int microsui_decode_sui_privkey(const char *privkey_bech, uint8_t privkey_bytes_
if (!convert_bits(ext_secret, &ext_len, words, words_len, 5, 8, false)) return -1;
if (ext_len != 33) return -1;
- memcpy(privkey_bytes_output, ext_secret + 1, 32);
+ memcpy(seed_out, ext_secret + 1, 32);
+
+ // Clear sensitive data from memory
+ crypto_wipe(ext_secret, sizeof ext_secret);
+ crypto_wipe(hrp_expanded, sizeof hrp_expanded);
+ crypto_wipe(words, sizeof words);
+ crypto_wipe(data5, sizeof data5);
+ crypto_wipe(str, sizeof str);
+
return 0;
}
/**
- * @brief Encode a 32-byte Sui private key into a Bech32 string.
+ * @brief Encode a 32-byte seed into a Sui Bech32 private key string.
*
- * Builds the Bech32 payload as: [1-byte scheme flag (0x00) | 32-byte secret],
+ * Builds the Bech32 payload as: [1-byte scheme flag (0x00) | 32-byte seed],
* converts to 5-bit words, appends checksum, and writes the Bech32 string with
* HRP = "suiprivkey".
*
- * @param[in] privkey_bytes Pointer to the 32-byte secret key.
- * @param[out] privkey_bech_output Output buffer for the null-terminated Bech32 string.
- * Must have capacity >= PK_BECH32_LEN + 1.
+ * @param[out] private_key_bech_out Output buffer for the null-terminated Bech32 string.
+ * @param[in] seed_bytes Pointer to the 32-byte seed.
+ * Must have capacity >= PK_BECH32_LEN + 1.
*
* @return 0 on success; -1 on conversion failure or insufficient output capacity.
*
* @note The output uses lowercase Bech32 alphabet and includes the null terminator.
* @note Callers are responsible for providing a sufficiently large output buffer.
*/
-int microsui_encode_sui_privkey(const uint8_t *privkey_bytes, char *privkey_bech_output) {
+int microsui_encode_bech32_private_key(char *private_key_bech_out, const uint8_t *seed) {
const char *hrp = "suiprivkey";
const uint8_t scheme_flag = 0x00;
const size_t output_len = PK_BECH32_LEN + 1;
uint8_t data[33];
data[0] = scheme_flag;
- memcpy(data + 1, privkey_bytes, 32);
+ memcpy(data + 1, seed, 32);
size_t data5_len = 0;
uint8_t data5[(33 * 8 + 4) / 5 + 1];
@@ -213,18 +220,24 @@ int microsui_encode_sui_privkey(const uint8_t *privkey_bytes, char *privkey_bech
}
for (size_t i = 0; i < hrp_len; i++) {
- privkey_bech_output[i] = hrp[i];
+ private_key_bech_out[i] = hrp[i];
}
- privkey_bech_output[hrp_len] = '1';
+ private_key_bech_out[hrp_len] = '1';
size_t idx = hrp_len + 1;
for (size_t i = 0; i < data5_len; i++) {
- privkey_bech_output[idx++] = ALPHABET[data5[i]];
+ private_key_bech_out[idx++] = ALPHABET[data5[i]];
}
for (int i = 0; i < 6; i++) {
- privkey_bech_output[idx++] = ALPHABET[checksum[i]];
+ private_key_bech_out[idx++] = ALPHABET[checksum[i]];
}
- privkey_bech_output[idx] = '\0'; // null-terminator
+ private_key_bech_out[idx] = '\0'; // null-terminator
+
+ // Clear sensitive data from memory
+ crypto_wipe(checksum, sizeof checksum);
+ crypto_wipe(data5, sizeof data5);
+ crypto_wipe(data, sizeof data);
+
return 0;
}
\ No newline at end of file
diff --git a/src/microsui_core/cryptography.h b/src/microsui_core/cryptography.h
index d29f2f9..0ca55e5 100644
--- a/src/microsui_core/cryptography.h
+++ b/src/microsui_core/cryptography.h
@@ -6,8 +6,8 @@
#define PK_BECH32_LEN 70 // Length of Sui private key in Bech32 format
-int microsui_decode_sui_privkey(const char *privkey_bech, uint8_t privkey_bytes_output[32]);
+int microsui_decode_bech32_private_key(uint8_t seed_out[32], const char *private_key_bech);
-int microsui_encode_sui_privkey(const uint8_t *privkey_bytes, char *privkey_bech_output);
+int microsui_encode_bech32_private_key(char *private_key_bech_out, const uint8_t *seed);
#endif
\ No newline at end of file
diff --git a/src/microsui_core/key_management.c b/src/microsui_core/key_management.c
index d191fc3..836497b 100644
--- a/src/microsui_core/key_management.c
+++ b/src/microsui_core/key_management.c
@@ -13,20 +13,20 @@
* then computes the BLAKE2b-256 hash of the 33-byte input.
* The resulting 32-byte digest is the canonical Sui address.
*
- * @param[in] pubkey 32-byte Ed25519 public key.
- * @param[out] sui_address_out Output buffer for the 32-byte Sui address.
+ * @param[out] sui_address_out Output buffer for the 32-byte Sui address.
+ * @param[in] public_key 32-byte Ed25519 public key.
*
* @return 0 on success; -1 if input pointers are NULL.
*
* @note This implementation follows the Sui address derivation convention:
- * sui_address = blake2b_256([scheme_flag | pubkey]).
+ * sui_address = blake2b_256([scheme_flag | public_key]).
*/
-int microsui_pubkey_to_sui_address(const uint8_t pubkey[32], uint8_t sui_address_out[32]) {
- if (!pubkey || !sui_address_out) return -1;
+int microsui_derive_sui_address_ed25519(uint8_t sui_address_out[32], const uint8_t public_key[32]) {
+ if (!public_key || !sui_address_out) return -1;
uint8_t input[33];
input[0] = 0x00; // flag de esquema: Ed25519
- memcpy(input + 1, pubkey, 32);
+ memcpy(input + 1, public_key, 32);
// Monocypher: hash_size = 32, msg = input (33 bytes)
crypto_blake2b(sui_address_out, 32, input, 33);
@@ -35,29 +35,33 @@ int microsui_pubkey_to_sui_address(const uint8_t pubkey[32], uint8_t sui_address
}
/**
- * @brief Derive a 32-byte Ed25519 public key from a 32-byte private key seed.
+ * @brief Derive a 32-byte Ed25519 public key from a 32-byte seed.
*
* Generates the full 64-byte Ed25519 secret key internally, then extracts
* the corresponding public key.
*
- * @param[in] private_key 32-byte Ed25519 private key seed.
- * @param[out] public_key Output buffer for the 32-byte public key.
+ * @param[out] public_key_out Output buffer for the 32-byte public key.
+ * @param[in] seed 32-byte Ed25519 seed.
*
* @return 0 on success; -1 if input pointers are NULL.
*
- * @note The private key is copied to a local buffer before use, to avoid
- * modifying the caller’s memory.
+ * @note The seed is copied to a local buffer before use,
+ * as the underlying library may modify it during key generation.
*/
-int get_public_key_from_private_key(const uint8_t private_key[32], uint8_t public_key[32]) {
- if (private_key == NULL || public_key == NULL) return -1;
+int microsui_derive_public_key_ed25519(uint8_t public_key_out[32], const uint8_t seed[32]) {
+ if (seed == NULL || public_key_out == NULL) return -1;
- // Copy private key to a local variable
- uint8_t private_key_cp[32];
- memcpy(private_key_cp, private_key, 32);
+ // Copy secret key to a local variable
+ uint8_t seed_cp[32];
+ memcpy(seed_cp, seed, 32);
- // Generate public key from private key using Ed25519
- uint8_t secret_key[64];
- crypto_ed25519_key_pair(secret_key, public_key, private_key_cp);
+ // Generate public key from secret key using Ed25519
+ uint8_t _[64]; // Placeholder for the secret key (not used here)
+ crypto_ed25519_key_pair(_, public_key_out, seed_cp);
+
+ // Clear sensitive data from memory
+ crypto_wipe(seed_cp, sizeof seed_cp);
+ crypto_wipe(_, sizeof _);
return 0;
}
\ No newline at end of file
diff --git a/src/microsui_core/key_management.h b/src/microsui_core/key_management.h
index 54d62e8..67146f0 100644
--- a/src/microsui_core/key_management.h
+++ b/src/microsui_core/key_management.h
@@ -4,8 +4,8 @@
#include
#include
-int microsui_pubkey_to_sui_address(const uint8_t pubkey[32], uint8_t sui_address_out[32]);
+int microsui_derive_sui_address_ed25519(uint8_t sui_address_out[32], const uint8_t pubkey[32]);
-int get_public_key_from_private_key(const uint8_t private_key[32], uint8_t public_key[32]);
+int microsui_derive_public_key_ed25519(uint8_t public_key_out[32], const uint8_t seed[32]);
#endif
\ No newline at end of file
diff --git a/src/microsui_core/lib/compact25519/c25519/README.md b/src/microsui_core/lib/compact25519/c25519/README.md
deleted file mode 100644
index e7587ed..0000000
--- a/src/microsui_core/lib/compact25519/c25519/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-This directory contains [Daniel Beer's (Public Domain) c25519 implementation](https://www.dlbeer.co.nz/oss/c25519.html),
-with some minor adjustments to add define guards.
-
-Version: 2017-10-05
\ No newline at end of file
diff --git a/src/microsui_core/lib/compact25519/c25519/c25519.c b/src/microsui_core/lib/compact25519/c25519/c25519.c
deleted file mode 100644
index 223ecf2..0000000
--- a/src/microsui_core/lib/compact25519/c25519/c25519.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/* Curve25519 (Montgomery form)
- * Daniel Beer , 18 Apr 2014
- *
- * This file is in the public domain.
- */
-
-#include "c25519.h"
-
-#ifndef COMPACT_DISABLE_X25519
-const uint8_t c25519_base_x[F25519_SIZE] = {9};
-
-/* Double an X-coordinate */
-static void xc_double(uint8_t *x3, uint8_t *z3,
- const uint8_t *x1, const uint8_t *z1)
-{
- /* Explicit formulas database: dbl-1987-m
- *
- * source 1987 Montgomery "Speeding the Pollard and elliptic
- * curve methods of factorization", page 261, fourth display
- * compute X3 = (X1^2-Z1^2)^2
- * compute Z3 = 4 X1 Z1 (X1^2 + a X1 Z1 + Z1^2)
- */
- uint8_t x1sq[F25519_SIZE];
- uint8_t z1sq[F25519_SIZE];
- uint8_t x1z1[F25519_SIZE];
- uint8_t a[F25519_SIZE];
-
- f25519_mul__distinct(x1sq, x1, x1);
- f25519_mul__distinct(z1sq, z1, z1);
- f25519_mul__distinct(x1z1, x1, z1);
-
- f25519_sub(a, x1sq, z1sq);
- f25519_mul__distinct(x3, a, a);
-
- f25519_mul_c(a, x1z1, 486662);
- f25519_add(a, x1sq, a);
- f25519_add(a, z1sq, a);
- f25519_mul__distinct(x1sq, x1z1, a);
- f25519_mul_c(z3, x1sq, 4);
-}
-
-/* Differential addition */
-static void xc_diffadd(uint8_t *x5, uint8_t *z5,
- const uint8_t *x1, const uint8_t *z1,
- const uint8_t *x2, const uint8_t *z2,
- const uint8_t *x3, const uint8_t *z3)
-{
- /* Explicit formulas database: dbl-1987-m3
- *
- * source 1987 Montgomery "Speeding the Pollard and elliptic curve
- * methods of factorization", page 261, fifth display, plus
- * common-subexpression elimination
- * compute A = X2+Z2
- * compute B = X2-Z2
- * compute C = X3+Z3
- * compute D = X3-Z3
- * compute DA = D A
- * compute CB = C B
- * compute X5 = Z1(DA+CB)^2
- * compute Z5 = X1(DA-CB)^2
- */
- uint8_t da[F25519_SIZE];
- uint8_t cb[F25519_SIZE];
- uint8_t a[F25519_SIZE];
- uint8_t b[F25519_SIZE];
-
- f25519_add(a, x2, z2);
- f25519_sub(b, x3, z3); /* D */
- f25519_mul__distinct(da, a, b);
-
- f25519_sub(b, x2, z2);
- f25519_add(a, x3, z3); /* C */
- f25519_mul__distinct(cb, a, b);
-
- f25519_add(a, da, cb);
- f25519_mul__distinct(b, a, a);
- f25519_mul__distinct(x5, z1, b);
-
- f25519_sub(a, da, cb);
- f25519_mul__distinct(b, a, a);
- f25519_mul__distinct(z5, x1, b);
-}
-
-void c25519_smult(uint8_t *result, const uint8_t *q, const uint8_t *e)
-{
- /* Current point: P_m */
- uint8_t xm[F25519_SIZE];
- uint8_t zm[F25519_SIZE] = {1};
-
- /* Predecessor: P_(m-1) */
- uint8_t xm1[F25519_SIZE] = {1};
- uint8_t zm1[F25519_SIZE] = {0};
-
- int i;
-
- /* Note: bit 254 is assumed to be 1 */
- f25519_copy(xm, q);
-
- for (i = 253; i >= 0; i--) {
- const int bit = (e[i >> 3] >> (i & 7)) & 1;
- uint8_t xms[F25519_SIZE];
- uint8_t zms[F25519_SIZE];
-
- /* From P_m and P_(m-1), compute P_(2m) and P_(2m-1) */
- xc_diffadd(xm1, zm1, q, f25519_one, xm, zm, xm1, zm1);
- xc_double(xm, zm, xm, zm);
-
- /* Compute P_(2m+1) */
- xc_diffadd(xms, zms, xm1, zm1, xm, zm, q, f25519_one);
-
- /* Select:
- * bit = 1 --> (P_(2m+1), P_(2m))
- * bit = 0 --> (P_(2m), P_(2m-1))
- */
- f25519_select(xm1, xm1, xm, bit);
- f25519_select(zm1, zm1, zm, bit);
- f25519_select(xm, xm, xms, bit);
- f25519_select(zm, zm, zms, bit);
- }
-
- /* Freeze out of projective coordinates */
- f25519_inv__distinct(zm1, zm);
- f25519_mul__distinct(result, zm1, xm);
- f25519_normalize(result);
-}
-#endif
diff --git a/src/microsui_core/lib/compact25519/c25519/c25519.h b/src/microsui_core/lib/compact25519/c25519/c25519.h
deleted file mode 100644
index eeac849..0000000
--- a/src/microsui_core/lib/compact25519/c25519/c25519.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Curve25519 (Montgomery form)
- * Daniel Beer , 18 Apr 2014
- *
- * This file is in the public domain.
- */
-
-#ifndef C25519_H_
-#define C25519_H_
-
-#ifndef COMPACT_DISABLE_X25519
-#include
-#include "f25519.h"
-
-/* Curve25519 has the equation over F(p = 2^255-19):
- *
- * y^2 = x^3 + 486662x^2 + x
- *
- * 486662 = 4A+2, where A = 121665. This is a Montgomery curve.
- *
- * For more information, see:
- *
- * Bernstein, D.J. (2006) "Curve25519: New Diffie-Hellman speed
- * records". Document ID: 4230efdfa673480fc079449d90f322c0.
- */
-
-/* This is the site of a Curve25519 exponent (private key) */
-#define C25519_EXPONENT_SIZE 32
-
-/* Having generated 32 random bytes, you should call this function to
- * finalize the generated key.
- */
-static inline void c25519_prepare(uint8_t *key)
-{
- key[0] &= 0xf8;
- key[31] &= 0x7f;
- key[31] |= 0x40;
-}
-
-/* X-coordinate of the base point */
-extern const uint8_t c25519_base_x[F25519_SIZE];
-
-/* X-coordinate scalar multiply: given the X-coordinate of q, return the
- * X-coordinate of e*q.
- *
- * result and q are field elements. e is an exponent.
- */
-void c25519_smult(uint8_t *result, const uint8_t *q, const uint8_t *e);
-#endif
-#endif
diff --git a/src/microsui_core/lib/compact25519/c25519/ed25519.c b/src/microsui_core/lib/compact25519/c25519/ed25519.c
deleted file mode 100644
index fb8cfa2..0000000
--- a/src/microsui_core/lib/compact25519/c25519/ed25519.c
+++ /dev/null
@@ -1,323 +0,0 @@
-/* Edwards curve operations
- * Daniel Beer , 9 Jan 2014
- *
- * This file is in the public domain.
- */
-
-#include "ed25519.h"
-
-#ifndef COMPACT_DISABLE_ED25519
-
-/* Base point is (numbers wrapped):
- *
- * x = 151122213495354007725011514095885315114
- * 54012693041857206046113283949847762202
- * y = 463168356949264781694283940034751631413
- * 07993866256225615783033603165251855960
- *
- * y is derived by transforming the original Montgomery base (u=9). x
- * is the corresponding positive coordinate for the new curve equation.
- * t is x*y.
- */
-const struct ed25519_pt ed25519_base = {
- .x = {
- 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9,
- 0xb2, 0xa7, 0x25, 0x95, 0x60, 0xc7, 0x2c, 0x69,
- 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
- 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
- },
- .y = {
- 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
- 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
- 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
- 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
- },
- .t = {
- 0xa3, 0xdd, 0xb7, 0xa5, 0xb3, 0x8a, 0xde, 0x6d,
- 0xf5, 0x52, 0x51, 0x77, 0x80, 0x9f, 0xf0, 0x20,
- 0x7d, 0xe3, 0xab, 0x64, 0x8e, 0x4e, 0xea, 0x66,
- 0x65, 0x76, 0x8b, 0xd7, 0x0f, 0x5f, 0x87, 0x67
- },
- .z = {1, 0}
-};
-
-const struct ed25519_pt ed25519_neutral = {
- .x = {0},
- .y = {1, 0},
- .t = {0},
- .z = {1, 0}
-};
-
-/* Conversion to and from projective coordinates */
-void ed25519_project(struct ed25519_pt *p,
- const uint8_t *x, const uint8_t *y)
-{
- f25519_copy(p->x, x);
- f25519_copy(p->y, y);
- f25519_load(p->z, 1);
- f25519_mul__distinct(p->t, x, y);
-}
-
-void ed25519_unproject(uint8_t *x, uint8_t *y,
- const struct ed25519_pt *p)
-{
- uint8_t z1[F25519_SIZE];
-
- f25519_inv__distinct(z1, p->z);
- f25519_mul__distinct(x, p->x, z1);
- f25519_mul__distinct(y, p->y, z1);
-
- f25519_normalize(x);
- f25519_normalize(y);
-}
-
-/* Compress/uncompress points. We compress points by storing the x
- * coordinate and the parity of the y coordinate.
- *
- * Rearranging the curve equation, we obtain explicit formulae for the
- * coordinates:
- *
- * x = sqrt((y^2-1) / (1+dy^2))
- * y = sqrt((x^2+1) / (1-dx^2))
- *
- * Where d = (-121665/121666), or:
- *
- * d = 370957059346694393431380835087545651895
- * 42113879843219016388785533085940283555
- */
-
-static const uint8_t ed25519_d[F25519_SIZE] = {
- 0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75,
- 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00,
- 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c,
- 0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52
-};
-
-void ed25519_pack(uint8_t *c, const uint8_t *x, const uint8_t *y)
-{
- uint8_t tmp[F25519_SIZE];
- uint8_t parity;
-
- f25519_copy(tmp, x);
- f25519_normalize(tmp);
- parity = (tmp[0] & 1) << 7;
-
- f25519_copy(c, y);
- f25519_normalize(c);
- c[31] |= parity;
-}
-
-uint8_t ed25519_try_unpack(uint8_t *x, uint8_t *y, const uint8_t *comp)
-{
- const int parity = comp[31] >> 7;
- uint8_t a[F25519_SIZE];
- uint8_t b[F25519_SIZE];
- uint8_t c[F25519_SIZE];
-
- /* Unpack y */
- f25519_copy(y, comp);
- y[31] &= 127;
-
- /* Compute c = y^2 */
- f25519_mul__distinct(c, y, y);
-
- /* Compute b = (1+dy^2)^-1 */
- f25519_mul__distinct(b, c, ed25519_d);
- f25519_add(a, b, f25519_one);
- f25519_inv__distinct(b, a);
-
- /* Compute a = y^2-1 */
- f25519_sub(a, c, f25519_one);
-
- /* Compute c = a*b = (y^2-1)/(1-dy^2) */
- f25519_mul__distinct(c, a, b);
-
- /* Compute a, b = +/-sqrt(c), if c is square */
- f25519_sqrt(a, c);
- f25519_neg(b, a);
-
- /* Select one of them, based on the compressed parity bit */
- f25519_select(x, a, b, (a[0] ^ parity) & 1);
-
- /* Verify that x^2 = c */
- f25519_mul__distinct(a, x, x);
- f25519_normalize(a);
- f25519_normalize(c);
-
- return f25519_eq(a, c);
-}
-
-/* k = 2d */
-static const uint8_t ed25519_k[F25519_SIZE] = {
- 0x59, 0xf1, 0xb2, 0x26, 0x94, 0x9b, 0xd6, 0xeb,
- 0x56, 0xb1, 0x83, 0x82, 0x9a, 0x14, 0xe0, 0x00,
- 0x30, 0xd1, 0xf3, 0xee, 0xf2, 0x80, 0x8e, 0x19,
- 0xe7, 0xfc, 0xdf, 0x56, 0xdc, 0xd9, 0x06, 0x24
-};
-
-void ed25519_add(struct ed25519_pt *r,
- const struct ed25519_pt *p1, const struct ed25519_pt *p2)
-{
- /* Explicit formulas database: add-2008-hwcd-3
- *
- * source 2008 Hisil--Wong--Carter--Dawson,
- * http://eprint.iacr.org/2008/522, Section 3.1
- * appliesto extended-1
- * parameter k
- * assume k = 2 d
- * compute A = (Y1-X1)(Y2-X2)
- * compute B = (Y1+X1)(Y2+X2)
- * compute C = T1 k T2
- * compute D = Z1 2 Z2
- * compute E = B - A
- * compute F = D - C
- * compute G = D + C
- * compute H = B + A
- * compute X3 = E F
- * compute Y3 = G H
- * compute T3 = E H
- * compute Z3 = F G
- */
- uint8_t a[F25519_SIZE];
- uint8_t b[F25519_SIZE];
- uint8_t c[F25519_SIZE];
- uint8_t d[F25519_SIZE];
- uint8_t e[F25519_SIZE];
- uint8_t f[F25519_SIZE];
- uint8_t g[F25519_SIZE];
- uint8_t h[F25519_SIZE];
-
- /* A = (Y1-X1)(Y2-X2) */
- f25519_sub(c, p1->y, p1->x);
- f25519_sub(d, p2->y, p2->x);
- f25519_mul__distinct(a, c, d);
-
- /* B = (Y1+X1)(Y2+X2) */
- f25519_add(c, p1->y, p1->x);
- f25519_add(d, p2->y, p2->x);
- f25519_mul__distinct(b, c, d);
-
- /* C = T1 k T2 */
- f25519_mul__distinct(d, p1->t, p2->t);
- f25519_mul__distinct(c, d, ed25519_k);
-
- /* D = Z1 2 Z2 */
- f25519_mul__distinct(d, p1->z, p2->z);
- f25519_add(d, d, d);
-
- /* E = B - A */
- f25519_sub(e, b, a);
-
- /* F = D - C */
- f25519_sub(f, d, c);
-
- /* G = D + C */
- f25519_add(g, d, c);
-
- /* H = B + A */
- f25519_add(h, b, a);
-
- /* X3 = E F */
- f25519_mul__distinct(r->x, e, f);
-
- /* Y3 = G H */
- f25519_mul__distinct(r->y, g, h);
-
- /* T3 = E H */
- f25519_mul__distinct(r->t, e, h);
-
- /* Z3 = F G */
- f25519_mul__distinct(r->z, f, g);
-}
-
-void ed25519_double(struct ed25519_pt *r, const struct ed25519_pt *p)
-{
- /* Explicit formulas database: dbl-2008-hwcd
- *
- * source 2008 Hisil--Wong--Carter--Dawson,
- * http://eprint.iacr.org/2008/522, Section 3.3
- * compute A = X1^2
- * compute B = Y1^2
- * compute C = 2 Z1^2
- * compute D = a A
- * compute E = (X1+Y1)^2-A-B
- * compute G = D + B
- * compute F = G - C
- * compute H = D - B
- * compute X3 = E F
- * compute Y3 = G H
- * compute T3 = E H
- * compute Z3 = F G
- */
- uint8_t a[F25519_SIZE];
- uint8_t b[F25519_SIZE];
- uint8_t c[F25519_SIZE];
- uint8_t e[F25519_SIZE];
- uint8_t f[F25519_SIZE];
- uint8_t g[F25519_SIZE];
- uint8_t h[F25519_SIZE];
-
- /* A = X1^2 */
- f25519_mul__distinct(a, p->x, p->x);
-
- /* B = Y1^2 */
- f25519_mul__distinct(b, p->y, p->y);
-
- /* C = 2 Z1^2 */
- f25519_mul__distinct(c, p->z, p->z);
- f25519_add(c, c, c);
-
- /* D = a A (alter sign) */
- /* E = (X1+Y1)^2-A-B */
- f25519_add(f, p->x, p->y);
- f25519_mul__distinct(e, f, f);
- f25519_sub(e, e, a);
- f25519_sub(e, e, b);
-
- /* G = D + B */
- f25519_sub(g, b, a);
-
- /* F = G - C */
- f25519_sub(f, g, c);
-
- /* H = D - B */
- f25519_neg(h, b);
- f25519_sub(h, h, a);
-
- /* X3 = E F */
- f25519_mul__distinct(r->x, e, f);
-
- /* Y3 = G H */
- f25519_mul__distinct(r->y, g, h);
-
- /* T3 = E H */
- f25519_mul__distinct(r->t, e, h);
-
- /* Z3 = F G */
- f25519_mul__distinct(r->z, f, g);
-}
-
-void ed25519_smult(struct ed25519_pt *r_out, const struct ed25519_pt *p,
- const uint8_t *e)
-{
- struct ed25519_pt r;
- int i;
-
- ed25519_copy(&r, &ed25519_neutral);
-
- for (i = 255; i >= 0; i--) {
- const uint8_t bit = (e[i >> 3] >> (i & 7)) & 1;
- struct ed25519_pt s;
-
- ed25519_double(&r, &r);
- ed25519_add(&s, &r, p);
-
- f25519_select(r.x, r.x, s.x, bit);
- f25519_select(r.y, r.y, s.y, bit);
- f25519_select(r.z, r.z, s.z, bit);
- f25519_select(r.t, r.t, s.t, bit);
- }
-
- ed25519_copy(r_out, &r);
-}
-#endif
diff --git a/src/microsui_core/lib/compact25519/c25519/ed25519.h b/src/microsui_core/lib/compact25519/c25519/ed25519.h
deleted file mode 100644
index 0e63467..0000000
--- a/src/microsui_core/lib/compact25519/c25519/ed25519.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* Edwards curve operations
- * Daniel Beer , 9 Jan 2014
- *
- * This file is in the public domain.
- */
-
-#ifndef ED25519_H_
-#define ED25519_H_
-
-#ifndef COMPACT_DISABLE_ED25519
-#include "f25519.h"
-
-/* This is not the Ed25519 signature system. Rather, we're implementing
- * basic operations on the twisted Edwards curve over (Z mod 2^255-19):
- *
- * -x^2 + y^2 = 1 - (121665/121666)x^2y^2
- *
- * With the positive-x base point y = 4/5.
- *
- * These functions will not leak secret data through timing.
- *
- * For more information, see:
- *
- * Bernstein, D.J. & Lange, T. (2007) "Faster addition and doubling on
- * elliptic curves". Document ID: 95616567a6ba20f575c5f25e7cebaf83.
- *
- * Hisil, H. & Wong, K K. & Carter, G. & Dawson, E. (2008) "Twisted
- * Edwards curves revisited". Advances in Cryptology, ASIACRYPT 2008,
- * Vol. 5350, pp. 326-343.
- */
-
-/* Projective coordinates */
-struct ed25519_pt {
- uint8_t x[F25519_SIZE];
- uint8_t y[F25519_SIZE];
- uint8_t t[F25519_SIZE];
- uint8_t z[F25519_SIZE];
-};
-
-extern const struct ed25519_pt ed25519_base;
-extern const struct ed25519_pt ed25519_neutral;
-
-/* Convert between projective and affine coordinates (x/y in F25519) */
-void ed25519_project(struct ed25519_pt *p,
- const uint8_t *x, const uint8_t *y);
-
-void ed25519_unproject(uint8_t *x, uint8_t *y,
- const struct ed25519_pt *p);
-
-/* Compress/uncompress points. try_unpack() will check that the
- * compressed point is on the curve, returning 1 if the unpacked point
- * is valid, and 0 otherwise.
- */
-#define ED25519_PACK_SIZE F25519_SIZE
-
-void ed25519_pack(uint8_t *c, const uint8_t *x, const uint8_t *y);
-uint8_t ed25519_try_unpack(uint8_t *x, uint8_t *y, const uint8_t *c);
-
-/* Add, double and scalar multiply */
-#define ED25519_EXPONENT_SIZE 32
-
-/* Prepare an exponent by clamping appropriate bits */
-static inline void ed25519_prepare(uint8_t *e)
-{
- e[0] &= 0xf8;
- e[31] &= 0x7f;
- e[31] |= 0x40;
-}
-
-/* Order of the group generated by the base point */
-static inline void ed25519_copy(struct ed25519_pt *dst,
- const struct ed25519_pt *src)
-{
- memcpy(dst, src, sizeof(*dst));
-}
-
-void ed25519_add(struct ed25519_pt *r,
- const struct ed25519_pt *a, const struct ed25519_pt *b);
-void ed25519_double(struct ed25519_pt *r, const struct ed25519_pt *a);
-void ed25519_smult(struct ed25519_pt *r, const struct ed25519_pt *a,
- const uint8_t *e);
-
-#endif
-#endif
diff --git a/src/microsui_core/lib/compact25519/c25519/edsign.c b/src/microsui_core/lib/compact25519/c25519/edsign.c
deleted file mode 100644
index cee3538..0000000
--- a/src/microsui_core/lib/compact25519/c25519/edsign.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/* Edwards curve signature system
- * Daniel Beer , 22 Apr 2014
- *
- * This file is in the public domain.
- */
-
-#include "ed25519.h"
-
-#ifndef COMPACT_DISABLE_ED25519
-#include "sha512.h"
-#include "fprime.h"
-#include "edsign.h"
-
-#define EXPANDED_SIZE 64
-
-static const uint8_t ed25519_order[FPRIME_SIZE] = {
- 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
- 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
-};
-
-static void expand_key(uint8_t *expanded, const uint8_t *secret)
-{
- struct sha512_state s;
-
- sha512_init(&s);
- sha512_final(&s, secret, EDSIGN_SECRET_KEY_SIZE);
- sha512_get(&s, expanded, 0, EXPANDED_SIZE);
- ed25519_prepare(expanded);
-}
-
-static uint8_t upp(struct ed25519_pt *p, const uint8_t *packed)
-{
- uint8_t x[F25519_SIZE];
- uint8_t y[F25519_SIZE];
- uint8_t ok = ed25519_try_unpack(x, y, packed);
-
- ed25519_project(p, x, y);
- return ok;
-}
-
-static void pp(uint8_t *packed, const struct ed25519_pt *p)
-{
- uint8_t x[F25519_SIZE];
- uint8_t y[F25519_SIZE];
-
- ed25519_unproject(x, y, p);
- ed25519_pack(packed, x, y);
-}
-
-static void sm_pack(uint8_t *r, const uint8_t *k)
-{
- struct ed25519_pt p;
-
- ed25519_smult(&p, &ed25519_base, k);
- pp(r, &p);
-}
-
-void edsign_sec_to_pub(uint8_t *pub, const uint8_t *secret)
-{
- uint8_t expanded[EXPANDED_SIZE];
-
- expand_key(expanded, secret);
- sm_pack(pub, expanded);
-}
-
-static void hash_with_prefix(uint8_t *out_fp,
- uint8_t *init_block, unsigned int prefix_size,
- const uint8_t *message, size_t len)
-{
- struct sha512_state s;
-
- sha512_init(&s);
-
- if (len < SHA512_BLOCK_SIZE && len + prefix_size < SHA512_BLOCK_SIZE) {
- memcpy(init_block + prefix_size, message, len);
- sha512_final(&s, init_block, len + prefix_size);
- } else {
- size_t i;
-
- memcpy(init_block + prefix_size, message,
- SHA512_BLOCK_SIZE - prefix_size);
- sha512_block(&s, init_block);
-
- for (i = SHA512_BLOCK_SIZE - prefix_size;
- i + SHA512_BLOCK_SIZE <= len;
- i += SHA512_BLOCK_SIZE)
- sha512_block(&s, message + i);
-
- sha512_final(&s, message + i, len + prefix_size);
- }
-
- sha512_get(&s, init_block, 0, SHA512_HASH_SIZE);
- fprime_from_bytes(out_fp, init_block, SHA512_HASH_SIZE, ed25519_order);
-}
-
-static void generate_k(uint8_t *k, const uint8_t *kgen_key,
- const uint8_t *message, size_t len)
-{
- uint8_t block[SHA512_BLOCK_SIZE];
-
- memcpy(block, kgen_key, 32);
- hash_with_prefix(k, block, 32, message, len);
-}
-
-static void hash_message(uint8_t *z, const uint8_t *r, const uint8_t *a,
- const uint8_t *m, size_t len)
-{
- uint8_t block[SHA512_BLOCK_SIZE];
-
- memcpy(block, r, 32);
- memcpy(block + 32, a, 32);
- hash_with_prefix(z, block, 64, m, len);
-}
-
-void edsign_sign(uint8_t *signature, const uint8_t *pub,
- const uint8_t *secret,
- const uint8_t *message, size_t len)
-{
- uint8_t expanded[EXPANDED_SIZE];
- uint8_t e[FPRIME_SIZE];
- uint8_t s[FPRIME_SIZE];
- uint8_t k[FPRIME_SIZE];
- uint8_t z[FPRIME_SIZE];
-
- expand_key(expanded, secret);
-
- /* Generate k and R = kB */
- generate_k(k, expanded + 32, message, len);
- sm_pack(signature, k);
-
- /* Compute z = H(R, A, M) */
- hash_message(z, signature, pub, message, len);
-
- /* Obtain e */
- fprime_from_bytes(e, expanded, 32, ed25519_order);
-
- /* Compute s = ze + k */
- fprime_mul(s, z, e, ed25519_order);
- fprime_add(s, k, ed25519_order);
- memcpy(signature + 32, s, 32);
-}
-
-uint8_t edsign_verify(const uint8_t *signature, const uint8_t *pub,
- const uint8_t *message, size_t len)
-{
- struct ed25519_pt p;
- struct ed25519_pt q;
- uint8_t lhs[F25519_SIZE];
- uint8_t rhs[F25519_SIZE];
- uint8_t z[FPRIME_SIZE];
- uint8_t ok = 1;
-
- /* Compute z = H(R, A, M) */
- hash_message(z, signature, pub, message, len);
-
- /* sB = (ze + k)B = ... */
- sm_pack(lhs, signature + 32);
-
- /* ... = zA + R */
- ok &= upp(&p, pub);
- ed25519_smult(&p, &p, z);
- ok &= upp(&q, signature);
- ed25519_add(&p, &p, &q);
- pp(rhs, &p);
-
- /* Equal? */
- return ok & f25519_eq(lhs, rhs);
-}
-#endif
diff --git a/src/microsui_core/lib/compact25519/c25519/edsign.h b/src/microsui_core/lib/compact25519/c25519/edsign.h
deleted file mode 100644
index cbdf904..0000000
--- a/src/microsui_core/lib/compact25519/c25519/edsign.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Edwards curve signature system
- * Daniel Beer , 22 Apr 2014
- *
- * This file is in the public domain.
- */
-
-#ifndef EDSIGN_H_
-#define EDSIGN_H_
-
-#ifndef COMPACT_DISABLE_ED25519
-#include
-#include
-
-/* This is the Ed25519 signature system, as described in:
- *
- * Daniel J. Bernstein, Niels Duif, Tanja Lange, Peter Schwabe, Bo-Yin
- * Yang. High-speed high-security signatures. Journal of Cryptographic
- * Engineering 2 (2012), 77-89. Document ID:
- * a1a62a2f76d23f65d622484ddd09caf8. URL:
- * http://cr.yp.to/papers.html#ed25519. Date: 2011.09.26.
- *
- * The format and calculation of signatures is compatible with the
- * Ed25519 implementation in SUPERCOP. Note, however, that our secret
- * keys are half the size: we don't store a copy of the public key in
- * the secret key (we generate it on demand).
- */
-
-/* Any string of 32 random bytes is a valid secret key. There is no
- * clamping of bits, because we don't use the key directly as an
- * exponent (the exponent is derived from part of a key expansion).
- */
-#define EDSIGN_SECRET_KEY_SIZE 32
-
-/* Given a secret key, produce the public key (a packed Edwards-curve
- * point).
- */
-#define EDSIGN_PUBLIC_KEY_SIZE 32
-
-void edsign_sec_to_pub(uint8_t *pub, const uint8_t *secret);
-
-/* Produce a signature for a message. */
-#define EDSIGN_SIGNATURE_SIZE 64
-
-void edsign_sign(uint8_t *signature, const uint8_t *pub,
- const uint8_t *secret,
- const uint8_t *message, size_t len);
-
-/* Verify a message signature. Returns non-zero if ok. */
-uint8_t edsign_verify(const uint8_t *signature, const uint8_t *pub,
- const uint8_t *message, size_t len);
-
-#endif
-#endif
diff --git a/src/microsui_core/lib/compact25519/c25519/f25519.c b/src/microsui_core/lib/compact25519/c25519/f25519.c
deleted file mode 100644
index c6e1bff..0000000
--- a/src/microsui_core/lib/compact25519/c25519/f25519.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/* Arithmetic mod p = 2^255-19
- * Daniel Beer , 5 Jan 2014
- *
- * This file is in the public domain.
- */
-
-#include "f25519.h"
-
-#ifdef FULL_C25519_CODE
-const uint8_t f25519_zero[F25519_SIZE] = {0};
-#endif
-const uint8_t f25519_one[F25519_SIZE] = {1};
-
-void f25519_load(uint8_t *x, uint32_t c)
-{
- unsigned int i;
-
- for (i = 0; i < sizeof(c); i++) {
- x[i] = c;
- c >>= 8;
- }
-
- for (; i < F25519_SIZE; i++)
- x[i] = 0;
-}
-
-void f25519_normalize(uint8_t *x)
-{
- uint8_t minusp[F25519_SIZE];
- uint16_t c;
- int i;
-
- /* Reduce using 2^255 = 19 mod p */
- c = (x[31] >> 7) * 19;
- x[31] &= 127;
-
- for (i = 0; i < F25519_SIZE; i++) {
- c += x[i];
- x[i] = c;
- c >>= 8;
- }
-
- /* The number is now less than 2^255 + 18, and therefore less than
- * 2p. Try subtracting p, and conditionally load the subtracted
- * value if underflow did not occur.
- */
- c = 19;
-
- for (i = 0; i + 1 < F25519_SIZE; i++) {
- c += x[i];
- minusp[i] = c;
- c >>= 8;
- }
-
- c += ((uint16_t)x[i]) - 128;
- minusp[31] = c;
-
- /* Load x-p if no underflow */
- f25519_select(x, minusp, x, (c >> 15) & 1);
-}
-
-uint8_t f25519_eq(const uint8_t *x, const uint8_t *y)
-{
- uint8_t sum = 0;
- int i;
-
- for (i = 0; i < F25519_SIZE; i++)
- sum |= x[i] ^ y[i];
-
- sum |= (sum >> 4);
- sum |= (sum >> 2);
- sum |= (sum >> 1);
-
- return (sum ^ 1) & 1;
-}
-
-void f25519_select(uint8_t *dst,
- const uint8_t *zero, const uint8_t *one,
- uint8_t condition)
-{
- const uint8_t mask = -condition;
- int i;
-
- for (i = 0; i < F25519_SIZE; i++)
- dst[i] = zero[i] ^ (mask & (one[i] ^ zero[i]));
-}
-
-void f25519_add(uint8_t *r, const uint8_t *a, const uint8_t *b)
-{
- uint16_t c = 0;
- int i;
-
- /* Add */
- for (i = 0; i < F25519_SIZE; i++) {
- c >>= 8;
- c += ((uint16_t)a[i]) + ((uint16_t)b[i]);
- r[i] = c;
- }
-
- /* Reduce with 2^255 = 19 mod p */
- r[31] &= 127;
- c = (c >> 7) * 19;
-
- for (i = 0; i < F25519_SIZE; i++) {
- c += r[i];
- r[i] = c;
- c >>= 8;
- }
-}
-
-void f25519_sub(uint8_t *r, const uint8_t *a, const uint8_t *b)
-{
- uint32_t c = 0;
- int i;
-
- /* Calculate a + 2p - b, to avoid underflow */
- c = 218;
- for (i = 0; i + 1 < F25519_SIZE; i++) {
- c += 65280 + ((uint32_t)a[i]) - ((uint32_t)b[i]);
- r[i] = c;
- c >>= 8;
- }
-
- c += ((uint32_t)a[31]) - ((uint32_t)b[31]);
- r[31] = c & 127;
- c = (c >> 7) * 19;
-
- for (i = 0; i < F25519_SIZE; i++) {
- c += r[i];
- r[i] = c;
- c >>= 8;
- }
-}
-
-void f25519_neg(uint8_t *r, const uint8_t *a)
-{
- uint32_t c = 0;
- int i;
-
- /* Calculate 2p - a, to avoid underflow */
- c = 218;
- for (i = 0; i + 1 < F25519_SIZE; i++) {
- c += 65280 - ((uint32_t)a[i]);
- r[i] = c;
- c >>= 8;
- }
-
- c -= ((uint32_t)a[31]);
- r[31] = c & 127;
- c = (c >> 7) * 19;
-
- for (i = 0; i < F25519_SIZE; i++) {
- c += r[i];
- r[i] = c;
- c >>= 8;
- }
-}
-
-void f25519_mul__distinct(uint8_t *r, const uint8_t *a, const uint8_t *b)
-{
- uint32_t c = 0;
- int i;
-
- for (i = 0; i < F25519_SIZE; i++) {
- int j;
-
- c >>= 8;
- for (j = 0; j <= i; j++)
- c += ((uint32_t)a[j]) * ((uint32_t)b[i - j]);
-
- for (; j < F25519_SIZE; j++)
- c += ((uint32_t)a[j]) *
- ((uint32_t)b[i + F25519_SIZE - j]) * 38;
-
- r[i] = c;
- }
-
- r[31] &= 127;
- c = (c >> 7) * 19;
-
- for (i = 0; i < F25519_SIZE; i++) {
- c += r[i];
- r[i] = c;
- c >>= 8;
- }
-}
-
-#ifdef FULL_C25519_CODE
-void f25519_mul(uint8_t *r, const uint8_t *a, const uint8_t *b)
-{
- uint8_t tmp[F25519_SIZE];
-
- f25519_mul__distinct(tmp, a, b);
- f25519_copy(r, tmp);
-}
-#endif
-
-void f25519_mul_c(uint8_t *r, const uint8_t *a, uint32_t b)
-{
- uint32_t c = 0;
- int i;
-
- for (i = 0; i < F25519_SIZE; i++) {
- c >>= 8;
- c += b * ((uint32_t)a[i]);
- r[i] = c;
- }
-
- r[31] &= 127;
- c >>= 7;
- c *= 19;
-
- for (i = 0; i < F25519_SIZE; i++) {
- c += r[i];
- r[i] = c;
- c >>= 8;
- }
-}
-
-void f25519_inv__distinct(uint8_t *r, const uint8_t *x)
-{
- uint8_t s[F25519_SIZE];
- int i;
-
- /* This is a prime field, so by Fermat's little theorem:
- *
- * x^(p-1) = 1 mod p
- *
- * Therefore, raise to (p-2) = 2^255-21 to get a multiplicative
- * inverse.
- *
- * This is a 255-bit binary number with the digits:
- *
- * 11111111... 01011
- *
- * We compute the result by the usual binary chain, but
- * alternate between keeping the accumulator in r and s, so as
- * to avoid copying temporaries.
- */
-
- /* 1 1 */
- f25519_mul__distinct(s, x, x);
- f25519_mul__distinct(r, s, x);
-
- /* 1 x 248 */
- for (i = 0; i < 248; i++) {
- f25519_mul__distinct(s, r, r);
- f25519_mul__distinct(r, s, x);
- }
-
- /* 0 */
- f25519_mul__distinct(s, r, r);
-
- /* 1 */
- f25519_mul__distinct(r, s, s);
- f25519_mul__distinct(s, r, x);
-
- /* 0 */
- f25519_mul__distinct(r, s, s);
-
- /* 1 */
- f25519_mul__distinct(s, r, r);
- f25519_mul__distinct(r, s, x);
-
- /* 1 */
- f25519_mul__distinct(s, r, r);
- f25519_mul__distinct(r, s, x);
-}
-
-#ifdef FULL_C25519_CODE
-void f25519_inv(uint8_t *r, const uint8_t *x)
-{
- uint8_t tmp[F25519_SIZE];
-
- f25519_inv__distinct(tmp, x);
- f25519_copy(r, tmp);
-}
-#endif
-
-/* Raise x to the power of (p-5)/8 = 2^252-3, using s for temporary
- * storage.
- */
-static void exp2523(uint8_t *r, const uint8_t *x, uint8_t *s)
-{
- int i;
-
- /* This number is a 252-bit number with the binary expansion:
- *
- * 111111... 01
- */
-
- /* 1 1 */
- f25519_mul__distinct(r, x, x);
- f25519_mul__distinct(s, r, x);
-
- /* 1 x 248 */
- for (i = 0; i < 248; i++) {
- f25519_mul__distinct(r, s, s);
- f25519_mul__distinct(s, r, x);
- }
-
- /* 0 */
- f25519_mul__distinct(r, s, s);
-
- /* 1 */
- f25519_mul__distinct(s, r, r);
- f25519_mul__distinct(r, s, x);
-}
-
-void f25519_sqrt(uint8_t *r, const uint8_t *a)
-{
- uint8_t v[F25519_SIZE];
- uint8_t i[F25519_SIZE];
- uint8_t x[F25519_SIZE];
- uint8_t y[F25519_SIZE];
-
- /* v = (2a)^((p-5)/8) [x = 2a] */
- f25519_mul_c(x, a, 2);
- exp2523(v, x, y);
-
- /* i = 2av^2 - 1 */
- f25519_mul__distinct(y, v, v);
- f25519_mul__distinct(i, x, y);
- f25519_load(y, 1);
- f25519_sub(i, i, y);
-
- /* r = avi */
- f25519_mul__distinct(x, v, a);
- f25519_mul__distinct(r, x, i);
-}
diff --git a/src/microsui_core/lib/compact25519/c25519/f25519.h b/src/microsui_core/lib/compact25519/c25519/f25519.h
deleted file mode 100644
index bb70fdc..0000000
--- a/src/microsui_core/lib/compact25519/c25519/f25519.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* Arithmetic mod p = 2^255-19
- * Daniel Beer , 8 Jan 2014
- *
- * This file is in the public domain.
- */
-
-#ifndef F25519_H_
-#define F25519_H_
-
-#include
-#include
-
-/* Field elements are represented as little-endian byte strings. All
- * operations have timings which are independent of input data, so they
- * can be safely used for cryptography.
- *
- * Computation is performed on un-normalized elements. These are byte
- * strings which fall into the range 0 <= x < 2p. Use f25519_normalize()
- * to convert to a value 0 <= x < p.
- *
- * Elements received from the outside may greater even than 2p.
- * f25519_normalize() will correctly deal with these numbers too.
- */
-#define F25519_SIZE 32
-
-/* Identity constants */
-#ifdef FULL_C25519_CODE
-extern const uint8_t f25519_zero[F25519_SIZE];
-#endif
-extern const uint8_t f25519_one[F25519_SIZE];
-
-/* Load a small constant */
-void f25519_load(uint8_t *x, uint32_t c);
-
-/* Copy two points */
-static inline void f25519_copy(uint8_t *x, const uint8_t *a)
-{
- memcpy(x, a, F25519_SIZE);
-}
-
-/* Normalize a field point x < 2*p by subtracting p if necessary */
-void f25519_normalize(uint8_t *x);
-
-/* Compare two field points in constant time. Return one if equal, zero
- * otherwise. This should be performed only on normalized values.
- */
-uint8_t f25519_eq(const uint8_t *x, const uint8_t *y);
-
-/* Conditional copy. If condition == 0, then zero is copied to dst. If
- * condition == 1, then one is copied to dst. Any other value results in
- * undefined behaviour.
- */
-void f25519_select(uint8_t *dst,
- const uint8_t *zero, const uint8_t *one,
- uint8_t condition);
-
-/* Add/subtract two field points. The three pointers are not required to
- * be distinct.
- */
-void f25519_add(uint8_t *r, const uint8_t *a, const uint8_t *b);
-void f25519_sub(uint8_t *r, const uint8_t *a, const uint8_t *b);
-
-/* Unary negation */
-void f25519_neg(uint8_t *r, const uint8_t *a);
-
-/* Multiply two field points. The __distinct variant is used when r is
- * known to be in a different location to a and b.
- */
-#ifdef FULL_C25519_CODE
-void f25519_mul(uint8_t *r, const uint8_t *a, const uint8_t *b);
-#endif
-void f25519_mul__distinct(uint8_t *r, const uint8_t *a, const uint8_t *b);
-
-/* Multiply a point by a small constant. The two pointers are not
- * required to be distinct.
- *
- * The constant must be less than 2^24.
- */
-void f25519_mul_c(uint8_t *r, const uint8_t *a, uint32_t b);
-
-/* Take the reciprocal of a field point. The __distinct variant is used
- * when r is known to be in a different location to x.
- */
-#ifdef FULL_C25519_CODE
-void f25519_inv(uint8_t *r, const uint8_t *x);
-#endif
-void f25519_inv__distinct(uint8_t *r, const uint8_t *x);
-
-/* Compute one of the square roots of the field element, if the element
- * is square. The other square is -r.
- *
- * If the input is not square, the returned value is a valid field
- * element, but not the correct answer. If you don't already know that
- * your element is square, you should square the return value and test.
- */
-void f25519_sqrt(uint8_t *r, const uint8_t *x);
-
-#endif
diff --git a/src/microsui_core/lib/compact25519/c25519/fprime.c b/src/microsui_core/lib/compact25519/c25519/fprime.c
deleted file mode 100644
index c1ea4b3..0000000
--- a/src/microsui_core/lib/compact25519/c25519/fprime.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/* Arithmetic in prime fields
- * Daniel Beer , 10 Jan 2014
- *
- * This file is in the public domain.
- */
-
-#include "fprime.h"
-
-#ifndef COMPACT_DISABLE_ED25519
-#ifdef FULL_C25519_CODE
-const uint8_t fprime_zero[FPRIME_SIZE] = {0};
-const uint8_t fprime_one[FPRIME_SIZE] = {1};
-#endif
-
-static void raw_add(uint8_t *x, const uint8_t *p)
-{
- uint16_t c = 0;
- int i;
-
- for (i = 0; i < FPRIME_SIZE; i++) {
- c += ((uint16_t)x[i]) + ((uint16_t)p[i]);
- x[i] = c;
- c >>= 8;
- }
-}
-
-static void raw_try_sub(uint8_t *x, const uint8_t *p)
-{
- uint8_t minusp[FPRIME_SIZE];
- uint16_t c = 0;
- int i;
-
- for (i = 0; i < FPRIME_SIZE; i++) {
- c = ((uint16_t)x[i]) - ((uint16_t)p[i]) - c;
- minusp[i] = c;
- c = (c >> 8) & 1;
- }
-
- fprime_select(x, minusp, x, c);
-}
-
-/* Warning: this function is variable-time */
-static int prime_msb(const uint8_t *p)
-{
- int i;
- uint8_t x;
-
- for (i = FPRIME_SIZE - 1; i >= 0; i--)
- if (p[i])
- break;
-
- x = p[i];
- i <<= 3;
-
- while (x) {
- x >>= 1;
- i++;
- }
-
- return i - 1;
-}
-
-/* Warning: this function may be variable-time in the argument n */
-static void shift_n_bits(uint8_t *x, int n)
-{
- uint16_t c = 0;
- int i;
-
- for (i = 0; i < FPRIME_SIZE; i++) {
- c |= ((uint16_t)x[i]) << n;
- x[i] = c;
- c >>= 8;
- }
-}
-
-#ifdef FULL_C25519_CODE
-void fprime_load(uint8_t *x, uint32_t c)
-{
- unsigned int i;
-
- for (i = 0; i < sizeof(c); i++) {
- x[i] = c;
- c >>= 8;
- }
-
- for (; i < FPRIME_SIZE; i++)
- x[i] = 0;
-}
-#endif
-
-static inline int min_int(int a, int b)
-{
- return a < b ? a : b;
-}
-
-void fprime_from_bytes(uint8_t *n,
- const uint8_t *x, size_t len,
- const uint8_t *modulus)
-{
- const int preload_total = min_int(prime_msb(modulus) - 1, len << 3);
- const int preload_bytes = preload_total >> 3;
- const int preload_bits = preload_total & 7;
- const int rbits = (len << 3) - preload_total;
- int i;
-
- memset(n, 0, FPRIME_SIZE);
-
- for (i = 0; i < preload_bytes; i++)
- n[i] = x[len - preload_bytes + i];
-
- if (preload_bits) {
- shift_n_bits(n, preload_bits);
- n[0] |= x[len - preload_bytes - 1] >> (8 - preload_bits);
- }
-
- for (i = rbits - 1; i >= 0; i--) {
- const uint8_t bit = (x[i >> 3] >> (i & 7)) & 1;
-
- shift_n_bits(n, 1);
- n[0] |= bit;
- raw_try_sub(n, modulus);
- }
-}
-
-#ifdef FULL_C25519_CODE
-void fprime_normalize(uint8_t *x, const uint8_t *modulus)
-{
- uint8_t n[FPRIME_SIZE];
-
- fprime_from_bytes(n, x, FPRIME_SIZE, modulus);
- fprime_copy(x, n);
-}
-
-uint8_t fprime_eq(const uint8_t *x, const uint8_t *y)
-{
- uint8_t sum = 0;
- int i;
-
- for (i = 0; i < FPRIME_SIZE; i++)
- sum |= x[i] ^ y[i];
-
- sum |= (sum >> 4);
- sum |= (sum >> 2);
- sum |= (sum >> 1);
-
- return (sum ^ 1) & 1;
-}
-#endif
-void fprime_select(uint8_t *dst,
- const uint8_t *zero, const uint8_t *one,
- uint8_t condition)
-{
- const uint8_t mask = -condition;
- int i;
-
- for (i = 0; i < FPRIME_SIZE; i++)
- dst[i] = zero[i] ^ (mask & (one[i] ^ zero[i]));
-}
-
-void fprime_add(uint8_t *r, const uint8_t *a, const uint8_t *modulus)
-{
- raw_add(r, a);
- raw_try_sub(r, modulus);
-}
-
-#ifdef FULL_C25519_CODE
-void fprime_sub(uint8_t *r, const uint8_t *a, const uint8_t *modulus)
-{
- raw_add(r, modulus);
- raw_try_sub(r, a);
- raw_try_sub(r, modulus);
-}
-#endif
-
-void fprime_mul(uint8_t *r, const uint8_t *a, const uint8_t *b,
- const uint8_t *modulus)
-{
- int i;
-
- memset(r, 0, FPRIME_SIZE);
-
- for (i = prime_msb(modulus); i >= 0; i--) {
- const uint8_t bit = (b[i >> 3] >> (i & 7)) & 1;
- uint8_t plusa[FPRIME_SIZE];
-
- shift_n_bits(r, 1);
- raw_try_sub(r, modulus);
-
- fprime_copy(plusa, r);
- fprime_add(plusa, a, modulus);
-
- fprime_select(r, r, plusa, bit);
- }
-}
-
-#ifdef FULL_C25519_CODE
-void fprime_inv(uint8_t *r, const uint8_t *a, const uint8_t *modulus)
-{
- uint8_t pm2[FPRIME_SIZE];
- uint16_t c = 2;
- int i;
-
- /* Compute (p-2) */
- fprime_copy(pm2, modulus);
- for (i = 0; i < FPRIME_SIZE; i++) {
- c = modulus[i] - c;
- pm2[i] = c;
- c >>= 8;
- }
-
- /* Binary exponentiation */
- fprime_load(r, 1);
-
- for (i = prime_msb(modulus); i >= 0; i--) {
- uint8_t r2[FPRIME_SIZE];
-
- fprime_mul(r2, r, r, modulus);
-
- if ((pm2[i >> 3] >> (i & 7)) & 1)
- fprime_mul(r, r2, a, modulus);
- else
- fprime_copy(r, r2);
- }
-}
-#endif
-#endif
diff --git a/src/microsui_core/lib/compact25519/c25519/fprime.h b/src/microsui_core/lib/compact25519/c25519/fprime.h
deleted file mode 100644
index 50c962d..0000000
--- a/src/microsui_core/lib/compact25519/c25519/fprime.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* Arithmetic in prime fields
- * Daniel Beer , 10 Jan 2014
- *
- * This file is in the public domain.
- */
-
-#ifndef FPRIME_H_
-#define FPRIME_H_
-
-#ifndef COMPACT_DISABLE_ED25519
-#include
-#include
-
-/* Maximum size of a field element (or a prime). Field elements are
- * always manipulated and stored in normalized form, with 0 <= x < p.
- * You can use normalize() to convert a denormalized bitstring to normal
- * form.
- *
- * Operations are constant with respect to the value of field elements,
- * but not with respect to the modulus.
- *
- * The modulus is a number p, such that 2p-1 fits in FPRIME_SIZE bytes.
- */
-#define FPRIME_SIZE 32
-
-#ifdef FULL_C25519_CODE
-/* Useful constants */
-extern const uint8_t fprime_zero[FPRIME_SIZE];
-extern const uint8_t fprime_one[FPRIME_SIZE];
-#endif
-
-#ifdef FULL_C25519_CODE
-/* Load a small constant */
-void fprime_load(uint8_t *x, uint32_t c);
-#endif
-
-/* Load a large constant */
-void fprime_from_bytes(uint8_t *n,
- const uint8_t *x, size_t len,
- const uint8_t *modulus);
-
-/* Copy an element */
-static inline void fprime_copy(uint8_t *x, const uint8_t *a)
-{
- memcpy(x, a, FPRIME_SIZE);
-}
-
-#ifdef FULL_C25519_CODE
-/* Normalize a field element */
-void fprime_normalize(uint8_t *x, const uint8_t *modulus);
-
-/* Compare two field points in constant time. Return one if equal, zero
- * otherwise. This should be performed only on normalized values.
- */
-uint8_t fprime_eq(const uint8_t *x, const uint8_t *y);
-
-#endif
-/* Conditional copy. If condition == 0, then zero is copied to dst. If
- * condition == 1, then one is copied to dst. Any other value results in
- * undefined behaviour.
- */
-void fprime_select(uint8_t *dst,
- const uint8_t *zero, const uint8_t *one,
- uint8_t condition);
-
-/* Add one value to another. The two pointers must be distinct. */
-void fprime_add(uint8_t *r, const uint8_t *a, const uint8_t *modulus);
-#ifdef FULL_C25519_CODE
-void fprime_sub(uint8_t *r, const uint8_t *a, const uint8_t *modulus);
-#endif
-
-/* Multiply two values to get a third. r must be distinct from a and b */
-void fprime_mul(uint8_t *r, const uint8_t *a, const uint8_t *b,
- const uint8_t *modulus);
-
-#ifdef FULL_C25519_CODE
-/* Compute multiplicative inverse. r must be distinct from a */
-void fprime_inv(uint8_t *r, const uint8_t *a, const uint8_t *modulus);
-#endif
-#endif
-#endif
diff --git a/src/microsui_core/lib/compact25519/c25519/sha512.c b/src/microsui_core/lib/compact25519/c25519/sha512.c
deleted file mode 100644
index 71f9a9d..0000000
--- a/src/microsui_core/lib/compact25519/c25519/sha512.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/* SHA512
- * Daniel Beer , 22 Apr 2014
- *
- * This file is in the public domain.
- */
-
-#include "sha512.h"
-
-#if !defined(COMPACT_DISABLE_ED25519) || !defined(COMPACT_DISABLE_X25519_DERIVE)
-const struct sha512_state sha512_initial_state = { {
- 0x6a09e667f3bcc908LL, 0xbb67ae8584caa73bLL,
- 0x3c6ef372fe94f82bLL, 0xa54ff53a5f1d36f1LL,
- 0x510e527fade682d1LL, 0x9b05688c2b3e6c1fLL,
- 0x1f83d9abfb41bd6bLL, 0x5be0cd19137e2179LL,
-} };
-
-static const uint64_t round_k[80] = {
- 0x428a2f98d728ae22LL, 0x7137449123ef65cdLL,
- 0xb5c0fbcfec4d3b2fLL, 0xe9b5dba58189dbbcLL,
- 0x3956c25bf348b538LL, 0x59f111f1b605d019LL,
- 0x923f82a4af194f9bLL, 0xab1c5ed5da6d8118LL,
- 0xd807aa98a3030242LL, 0x12835b0145706fbeLL,
- 0x243185be4ee4b28cLL, 0x550c7dc3d5ffb4e2LL,
- 0x72be5d74f27b896fLL, 0x80deb1fe3b1696b1LL,
- 0x9bdc06a725c71235LL, 0xc19bf174cf692694LL,
- 0xe49b69c19ef14ad2LL, 0xefbe4786384f25e3LL,
- 0x0fc19dc68b8cd5b5LL, 0x240ca1cc77ac9c65LL,
- 0x2de92c6f592b0275LL, 0x4a7484aa6ea6e483LL,
- 0x5cb0a9dcbd41fbd4LL, 0x76f988da831153b5LL,
- 0x983e5152ee66dfabLL, 0xa831c66d2db43210LL,
- 0xb00327c898fb213fLL, 0xbf597fc7beef0ee4LL,
- 0xc6e00bf33da88fc2LL, 0xd5a79147930aa725LL,
- 0x06ca6351e003826fLL, 0x142929670a0e6e70LL,
- 0x27b70a8546d22ffcLL, 0x2e1b21385c26c926LL,
- 0x4d2c6dfc5ac42aedLL, 0x53380d139d95b3dfLL,
- 0x650a73548baf63deLL, 0x766a0abb3c77b2a8LL,
- 0x81c2c92e47edaee6LL, 0x92722c851482353bLL,
- 0xa2bfe8a14cf10364LL, 0xa81a664bbc423001LL,
- 0xc24b8b70d0f89791LL, 0xc76c51a30654be30LL,
- 0xd192e819d6ef5218LL, 0xd69906245565a910LL,
- 0xf40e35855771202aLL, 0x106aa07032bbd1b8LL,
- 0x19a4c116b8d2d0c8LL, 0x1e376c085141ab53LL,
- 0x2748774cdf8eeb99LL, 0x34b0bcb5e19b48a8LL,
- 0x391c0cb3c5c95a63LL, 0x4ed8aa4ae3418acbLL,
- 0x5b9cca4f7763e373LL, 0x682e6ff3d6b2b8a3LL,
- 0x748f82ee5defb2fcLL, 0x78a5636f43172f60LL,
- 0x84c87814a1f0ab72LL, 0x8cc702081a6439ecLL,
- 0x90befffa23631e28LL, 0xa4506cebde82bde9LL,
- 0xbef9a3f7b2c67915LL, 0xc67178f2e372532bLL,
- 0xca273eceea26619cLL, 0xd186b8c721c0c207LL,
- 0xeada7dd6cde0eb1eLL, 0xf57d4f7fee6ed178LL,
- 0x06f067aa72176fbaLL, 0x0a637dc5a2c898a6LL,
- 0x113f9804bef90daeLL, 0x1b710b35131c471bLL,
- 0x28db77f523047d84LL, 0x32caab7b40c72493LL,
- 0x3c9ebe0a15c9bebcLL, 0x431d67c49c100d4cLL,
- 0x4cc5d4becb3e42b6LL, 0x597f299cfc657e2aLL,
- 0x5fcb6fab3ad6faecLL, 0x6c44198c4a475817LL,
-};
-
-static inline uint64_t load64(const uint8_t *x)
-{
- uint64_t r;
-
- r = *(x++);
- r = (r << 8) | *(x++);
- r = (r << 8) | *(x++);
- r = (r << 8) | *(x++);
- r = (r << 8) | *(x++);
- r = (r << 8) | *(x++);
- r = (r << 8) | *(x++);
- r = (r << 8) | *(x++);
-
- return r;
-}
-
-static inline void store64(uint8_t *x, uint64_t v)
-{
- x += 7;
- *(x--) = v;
- v >>= 8;
- *(x--) = v;
- v >>= 8;
- *(x--) = v;
- v >>= 8;
- *(x--) = v;
- v >>= 8;
- *(x--) = v;
- v >>= 8;
- *(x--) = v;
- v >>= 8;
- *(x--) = v;
- v >>= 8;
- *(x--) = v;
-}
-
-static inline uint64_t rot64(uint64_t x, int bits)
-{
- return (x >> bits) | (x << (64 - bits));
-}
-
-void sha512_block(struct sha512_state *s, const uint8_t *blk)
-{
- uint64_t w[16];
- uint64_t a, b, c, d, e, f, g, h;
- int i;
-
- for (i = 0; i < 16; i++) {
- w[i] = load64(blk);
- blk += 8;
- }
-
- /* Load state */
- a = s->h[0];
- b = s->h[1];
- c = s->h[2];
- d = s->h[3];
- e = s->h[4];
- f = s->h[5];
- g = s->h[6];
- h = s->h[7];
-
- for (i = 0; i < 80; i++) {
- /* Compute value of w[i + 16]. w[wrap(i)] is currently w[i] */
- const uint64_t wi = w[i & 15];
- const uint64_t wi15 = w[(i + 1) & 15];
- const uint64_t wi2 = w[(i + 14) & 15];
- const uint64_t wi7 = w[(i + 9) & 15];
- const uint64_t s0 =
- rot64(wi15, 1) ^ rot64(wi15, 8) ^ (wi15 >> 7);
- const uint64_t s1 =
- rot64(wi2, 19) ^ rot64(wi2, 61) ^ (wi2 >> 6);
-
- /* Round calculations */
- const uint64_t S0 = rot64(a, 28) ^ rot64(a, 34) ^ rot64(a, 39);
- const uint64_t S1 = rot64(e, 14) ^ rot64(e, 18) ^ rot64(e, 41);
- const uint64_t ch = (e & f) ^ ((~e) & g);
- const uint64_t temp1 = h + S1 + ch + round_k[i] + wi;
- const uint64_t maj = (a & b) ^ (a & c) ^ (b & c);
- const uint64_t temp2 = S0 + maj;
-
- /* Update round state */
- h = g;
- g = f;
- f = e;
- e = d + temp1;
- d = c;
- c = b;
- b = a;
- a = temp1 + temp2;
-
- /* w[wrap(i)] becomes w[i + 16] */
- w[i & 15] = wi + s0 + wi7 + s1;
- }
-
- /* Store state */
- s->h[0] += a;
- s->h[1] += b;
- s->h[2] += c;
- s->h[3] += d;
- s->h[4] += e;
- s->h[5] += f;
- s->h[6] += g;
- s->h[7] += h;
-}
-
-void sha512_final(struct sha512_state *s, const uint8_t *blk,
- size_t total_size)
-{
- uint8_t temp[SHA512_BLOCK_SIZE] = {0};
- const size_t last_size = total_size & (SHA512_BLOCK_SIZE - 1);
-
- if (last_size)
- memcpy(temp, blk, last_size);
- temp[last_size] = 0x80;
-
- if (last_size > 111) {
- sha512_block(s, temp);
- memset(temp, 0, sizeof(temp));
- }
-
- /* Note: we assume total_size fits in 61 bits */
- store64(temp + SHA512_BLOCK_SIZE - 8, total_size << 3);
- sha512_block(s, temp);
-}
-
-void sha512_get(const struct sha512_state *s, uint8_t *hash,
- unsigned int offset, unsigned int len)
-{
- int i;
-
- if (offset > SHA512_BLOCK_SIZE)
- return;
-
- if (len > SHA512_BLOCK_SIZE - offset)
- len = SHA512_BLOCK_SIZE - offset;
-
- /* Skip whole words */
- i = offset >> 3;
- offset &= 7;
-
- /* Skip/read out bytes */
- if (offset) {
- uint8_t tmp[8];
- unsigned int c = 8 - offset;
-
- if (c > len)
- c = len;
-
- store64(tmp, s->h[i++]);
- memcpy(hash, tmp + offset, c);
- len -= c;
- hash += c;
- }
-
- /* Read out whole words */
- while (len >= 8) {
- store64(hash, s->h[i++]);
- hash += 8;
- len -= 8;
- }
-
- /* Read out bytes */
- if (len) {
- uint8_t tmp[8];
-
- store64(tmp, s->h[i]);
- memcpy(hash, tmp, len);
- }
-}
-#endif
diff --git a/src/microsui_core/lib/compact25519/c25519/sha512.h b/src/microsui_core/lib/compact25519/c25519/sha512.h
deleted file mode 100644
index 881118e..0000000
--- a/src/microsui_core/lib/compact25519/c25519/sha512.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* SHA512
- * Daniel Beer , 22 Apr 2014
- *
- * This file is in the public domain.
- */
-
-#ifndef SHA512_H_
-#define SHA512_H_
-
-#if !defined(COMPACT_DISABLE_ED25519) || !defined(COMPACT_DISABLE_X25519_DERIVE)
-#include
-#include
-#include
-
-/* SHA512 state. State is updated as data is fed in, and then the final
- * hash can be read out in slices.
- *
- * Data is fed in as a sequence of full blocks terminated by a single
- * partial block.
- */
-struct sha512_state {
- uint64_t h[8];
-};
-
-/* Initial state */
-extern const struct sha512_state sha512_initial_state;
-
-/* Set up a new context */
-static inline void sha512_init(struct sha512_state *s)
-{
- memcpy(s, &sha512_initial_state, sizeof(*s));
-}
-
-/* Feed a full block in */
-#define SHA512_BLOCK_SIZE 128
-
-void sha512_block(struct sha512_state *s, const uint8_t *blk);
-
-/* Feed the last partial block in. The total stream size must be
- * specified. The size of the block given is assumed to be (total_size %
- * SHA512_BLOCK_SIZE). This might be zero, but you still need to call
- * this function to terminate the stream.
- */
-void sha512_final(struct sha512_state *s, const uint8_t *blk,
- size_t total_size);
-
-/* Fetch a slice of the hash result. */
-#define SHA512_HASH_SIZE 64
-
-void sha512_get(const struct sha512_state *s, uint8_t *hash,
- unsigned int offset, unsigned int len);
-
-#endif
-#endif
diff --git a/src/microsui_core/lib/compact25519/compact_ed25519.c b/src/microsui_core/lib/compact25519/compact_ed25519.c
deleted file mode 100644
index 26d07e9..0000000
--- a/src/microsui_core/lib/compact25519/compact_ed25519.c
+++ /dev/null
@@ -1,46 +0,0 @@
-#include "compact_ed25519.h"
-
-#ifndef COMPACT_DISABLE_ED25519
-#include "c25519/edsign.h"
-#include "compact_wipe.h"
-#include
-
-#define __PUBLIC_KEY_OFFSET (32)
-
-void compact_ed25519_keygen(
- uint8_t private_key[ED25519_PRIVATE_KEY_SIZE],
- uint8_t public_key[ED25519_PUBLIC_KEY_SIZE],
- uint8_t random_seed[ED25519_SEED_SIZE]
-) {
- // private key is seed + public key, like golang and others
- edsign_sec_to_pub(public_key, random_seed);
- memcpy(private_key, random_seed, ED25519_SEED_SIZE);
- memcpy(private_key + __PUBLIC_KEY_OFFSET, public_key, ED25519_PUBLIC_KEY_SIZE);
- compact_wipe(random_seed, ED25519_SEED_SIZE);
-}
-
-void compact_ed25519_calc_public_key(
- uint8_t public_key[ED25519_PUBLIC_KEY_SIZE],
- const uint8_t private_key[ED25519_PRIVATE_KEY_SIZE]
-) {
- memcpy(public_key, private_key + __PUBLIC_KEY_OFFSET, ED25519_PUBLIC_KEY_SIZE);
-}
-
-void compact_ed25519_sign(
- uint8_t signature[ED25519_SIGNATURE_SIZE],
- const uint8_t private_key[ED25519_PRIVATE_KEY_SIZE],
- const void *message,
- size_t msg_length
-) {
- edsign_sign(signature, private_key + __PUBLIC_KEY_OFFSET, private_key, message, msg_length);
-}
-
-bool compact_ed25519_verify(
- const uint8_t signature[ED25519_SIGNATURE_SIZE],
- const uint8_t public_key[ED25519_PUBLIC_KEY_SIZE],
- const void *message,
- size_t msg_length
-) {
- return edsign_verify(signature, public_key, message, msg_length) != 0;
-}
-#endif
diff --git a/src/microsui_core/lib/compact25519/compact_ed25519.h b/src/microsui_core/lib/compact25519/compact_ed25519.h
deleted file mode 100644
index a78a601..0000000
--- a/src/microsui_core/lib/compact25519/compact_ed25519.h
+++ /dev/null
@@ -1,110 +0,0 @@
-#ifndef _COMPACT_ED25519_H
-#define _COMPACT_ED25519_H
-
-#ifndef COMPACT_DISABLE_ED25519
-/*
- Ed25519 signs messages using Curve25519.
-
- After pre-sharing a public key, it allows two parties to verify the other side
- is who they say they are and that the communication is not altered.
-
- A signature is a ED25519_SIGNATURE_SIZE size byte array that can be only be
- generated when you have the private key, but can be verified if you have
- the public key.
-
- As an example: two parties want to have rotating keys for their encryption.
- The only thing they need to know about eachother is their long term Ed25519
- public key. Per session they perform a X25519 key exchange, but sign their
- "Ephemeral" public key with their long-term Ed25519 private key. Now they can
- share this public key (and the signature) over a cleartext channel, nobody can
- alter of impersonate this exchange.
-
- (this is roughly how TLS works)
-*/
-#include
-#include
-#include
-
-#define ED25519_SEED_SIZE (32)
-#define ED25519_PUBLIC_KEY_SIZE (32)
-#define ED25519_PRIVATE_KEY_SIZE (64)
-#define ED25519_SIGNATURE_SIZE (64)
-
-/*
- Generate a private signing key from a random seed.
-
- input:
- - random_seed = random bytes that need to be filled from a good source of
- random entropy, PLEASE research the options on your platform!
-
- output:
- - private_key = signing key than can be used for compact_ed25519_sign
- - public_key = key to share with other parties
-
- (internally the format of the private key is the seed + public key,
- this makes it compatible with keys coming from libsodium, golang, and
- implentations that derive from SUPERCOP/ref10)
-*/
-void compact_ed25519_keygen(
- uint8_t private_key[ED25519_PRIVATE_KEY_SIZE],
- uint8_t public_key[ED25519_PUBLIC_KEY_SIZE],
- uint8_t random_seed[ED25519_SEED_SIZE]
-);
-
-/*
- Extract public key from private key
-
- input:
- - private_key = signing key generated with compact_ed25519_keygen
-
- output:
- - public_key = public key corresponding to this private key, share with
- interested parties
-*/
-void compact_ed25519_calc_public_key(
- uint8_t public_key[ED25519_PUBLIC_KEY_SIZE],
- const uint8_t private_key[ED25519_PRIVATE_KEY_SIZE]
-);
-
-/*
- Sign a message with the private key.
-
- input:
- - private_key = signing key generated with compact_ed25519_keygen or from a
- compatible source
- - message = pointer to the data that needs to be signed
- - msg_length = how many bytes to read from the start of the message pointer
- output:
- - signature = the signature that proves you hold the private key and that
- nobody tried to change the message. (the second property only holds
- if the attacker cannot change the size of the message)
-*/
-void compact_ed25519_sign(
- uint8_t signature[ED25519_SIGNATURE_SIZE],
- const uint8_t private_key[ED25519_PRIVATE_KEY_SIZE],
- const void *message,
- size_t msg_length
-);
-
-/*
- Verify a signature against a public key.
-
- input:
- - signature = which signature to verify
- - public_key = the public key that it should be verified against
- (should not have been part of the message that contained the signature)
- - message = message to verify
- - msg_length = size of the message to verify
-
- returns:
- true if verified
-*/
-bool compact_ed25519_verify(
- const uint8_t signature[ED25519_SIGNATURE_SIZE],
- const uint8_t public_key[ED25519_PUBLIC_KEY_SIZE],
- const void *message,
- size_t msg_length
-);
-#endif
-
-#endif
diff --git a/src/microsui_core/lib/compact25519/compact_wipe.c b/src/microsui_core/lib/compact25519/compact_wipe.c
deleted file mode 100644
index e3c7049..0000000
--- a/src/microsui_core/lib/compact25519/compact_wipe.c
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "compact_wipe.h"
-#include
-#include
-
-void *compact_wipe(void *data, size_t length) {
-// simplification of: https://www.cryptologie.net/article/419/zeroing-memory-compiler-optimizations-and-memset_s/
- volatile unsigned char *p = data;
- while (length--){
- *p++ = 0;
- }
- return data;
-}
diff --git a/src/microsui_core/lib/compact25519/compact_wipe.h b/src/microsui_core/lib/compact25519/compact_wipe.h
deleted file mode 100644
index cd348e0..0000000
--- a/src/microsui_core/lib/compact25519/compact_wipe.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef __COMPACT_WIPE_H
-#define __COMPACT_WIPE_H
-#include
-#include
-/*
- Try to wipe contents of a buffer, as best as we can.
- (memset can be ignored by the compiler)
-
- Use this to clear private key data if you do not need it anymore.
-
- returns the data pointer, makes for easier chaining
-*/
-void *compact_wipe(void *data, size_t length);
-#endif
diff --git a/src/microsui_core/lib/compact25519/compact_x25519.c b/src/microsui_core/lib/compact25519/compact_x25519.c
deleted file mode 100644
index 7733764..0000000
--- a/src/microsui_core/lib/compact25519/compact_x25519.c
+++ /dev/null
@@ -1,68 +0,0 @@
-
-#ifndef COMPACT_DISABLE_X25519
-#include "compact_x25519.h"
-#include "c25519/c25519.h"
-#include "c25519/sha512.h"
-#include "compact_wipe.h"
-
-void compact_x25519_keygen(
- uint8_t private_key[X25519_KEY_SIZE],
- uint8_t public_key[X25519_KEY_SIZE],
- uint8_t random_seed[X25519_KEY_SIZE]
-) {
- memcpy(private_key, random_seed, X25519_KEY_SIZE);
- compact_wipe(random_seed, X25519_KEY_SIZE);
- c25519_prepare(private_key);
- c25519_smult(public_key, c25519_base_x, private_key);
-}
-
-void compact_x25519_shared(
- uint8_t shared_secret[X25519_SHARED_SIZE],
- const uint8_t my_private_key[X25519_KEY_SIZE],
- const uint8_t their_public_key[X25519_KEY_SIZE]
-) {
- // Ensure that supplied private key is clamped (fix issue #1).
- // Calling `c25519_prepare` multiple times for the same private key
- // is OK because it won't modify already clamped key.
- uint8_t clamped_private_key[X25519_KEY_SIZE];
- memcpy(clamped_private_key, my_private_key, X25519_KEY_SIZE);
- c25519_prepare(clamped_private_key);
- c25519_smult(shared_secret, their_public_key, clamped_private_key);
- compact_wipe(clamped_private_key, X25519_KEY_SIZE);
-}
-
-#ifndef COMPACT_DISABLE_X25519_DERIVE
-#if (X25519_KEY_SIZE + (2 * X25519_KEY_SIZE)) > SHA512_BLOCK_SIZE
-#error "Unexpected key sizes"
-#endif
-
-static uint8_t* append(uint8_t *dst, const void * source, size_t length) {
- memcpy(dst, source, length);
- return dst + length;
-}
-
-void compact_x25519_derive_encryption_key(
- uint8_t *encryption_key,
- size_t key_size,
- const uint8_t shared_secret[X25519_SHARED_SIZE],
- const uint8_t public_key1[X25519_KEY_SIZE],
- const uint8_t public_key2[X25519_KEY_SIZE]
-) {
- if (key_size > SHA512_HASH_SIZE) {
- key_size = SHA512_HASH_SIZE;
- }
- uint8_t key_data[X25519_SHARED_SIZE + 2 * X25519_KEY_SIZE];
- uint8_t *p = key_data;
- p = append(p, shared_secret, X25519_SHARED_SIZE);
- p = append(p, public_key1, X25519_KEY_SIZE);
- append(p, public_key2, X25519_KEY_SIZE);
-
- struct sha512_state hasher;
- sha512_init(&hasher);
- sha512_final(&hasher, key_data, sizeof(key_data));
- sha512_get(&hasher, encryption_key, 0, key_size);
-
- compact_wipe(key_data, X25519_SHARED_SIZE); // clear the session key at least
-}
-#endif
-#endif
diff --git a/src/microsui_core/lib/compact25519/compact_x25519.h b/src/microsui_core/lib/compact25519/compact_x25519.h
deleted file mode 100644
index 41879b8..0000000
--- a/src/microsui_core/lib/compact25519/compact_x25519.h
+++ /dev/null
@@ -1,101 +0,0 @@
-#ifndef _COMPACT_X25519_H
-#define _COMPACT_X25519_H
-
-#ifndef COMPACT_DISABLE_X25519
-/*
- X25519 is a DH key exchange over Curve25519.
-
- Two parties can share their public keys over an open channel and agree upon
- a shared secret, that a third party cannot derive.
-
- Security concern: if a third party can intercept and change your connection in
- some way, then X25519 is not enough. The third party could for example run
- two X25519 sessions, one between themselfs and you, and another one between
- themselfs and the server. X25519 has no protection against this.
-
- A possible solution is to use Ed25519 to sign the public keys exchanged, with a
- special set of keys that is known before hand. Depending on your scenario, this
- either means embedding a set of long-term keys in your application or setting up
- some kind of Public Key Infrastructure (PKI).
-
- If that sounds to complicated or would not work for your case, checkout
- the Noise framework. It is a bit less compact than X25519 + Ed25519 but much
- more flexible in the kind of session setup styles.
-*/
-
-#include
-#include
-
-#define X25519_KEY_SIZE (32)
-#define X25519_SHARED_SIZE (32)
-
-/*
- Calculate public & private keypair for X25519 key exchange.
- Never transmit the private_key!
-
- input:
- - random_seed = random bytes that need to be filled from a good source of
- random entropy, PLEASE research the options on your platform!
-
- output:
- - private_key = resulting private key, never share this with the other party
- - public_key = public key to be shared with the other party
-*/
-void compact_x25519_keygen(
- uint8_t private_key[X25519_KEY_SIZE],
- uint8_t public_key[X25519_KEY_SIZE],
- uint8_t random_seed[X25519_KEY_SIZE]
-);
-
-/*
- Calculate shared secret based on the others side public key.
- The shared secret does not have a uniform distribution so common advice
- is to avoid using it directly as a key. You can use
- compact_x25519_derive_encryption_key to get a more suitable encryption
- key out of this shared secret
-
- input:
- - my_private_key = private key that came out of compact_x25519_keygen
- - their_public_key = public key that was shared by the other party
-
- output:
- - shared_secret = X25519_SHARED_SIZE bytes that both sides now share
-*/
-void compact_x25519_shared(
- uint8_t shared_secret[X25519_SHARED_SIZE],
- const uint8_t my_private_key[X25519_KEY_SIZE],
- const uint8_t their_public_key[X25519_KEY_SIZE]
-);
-
-#ifndef COMPACT_DISABLE_X25519_DERIVE
-/*
- Derive an more suitable encryption key from the shared secret.
- This is not part of the normal X25519 specification, but the specifications
- does warn that the shared secret is less suited as symmetric encryption key.
-
- The encryption key is the result of
- sha512(concat(shared_secret, public_key1, public_key2))[0..key_size]
-
- You have to make sure both parties agree which public key goes in first.
-
- input:
- - key_size = number between 1 and 64, of how big your encryption_key
- needs to be, make sure there is enough room where
- the encryption_key points to
- - shared_secret = result of compact_x25519_shared
- - public_key1 = first public key to mix in with the key
- - public_key2 = second public key to mix in with the key
-
- output:
- - encryption_key = supplied buffer is filled with a encryption key
-*/
-void compact_x25519_derive_encryption_key(
- uint8_t *encryption_key,
- size_t key_size,
- const uint8_t shared_secret[X25519_SHARED_SIZE],
- const uint8_t public_key1[X25519_KEY_SIZE],
- const uint8_t public_key2[X25519_KEY_SIZE]
-);
-#endif
-#endif
-#endif
diff --git a/src/microsui_core/lib/monocypher/monocypher.c b/src/microsui_core/lib/monocypher/monocypher.c
index b9f26d4..840f238 100644
--- a/src/microsui_core/lib/monocypher/monocypher.c
+++ b/src/microsui_core/lib/monocypher/monocypher.c
@@ -3382,6 +3382,104 @@ int crypto_ed25519_ph_check(const uint8_t sig[64], const uint8_t pk[32],
}
+// Added by MicroSui: Ed25519 signature (pure / RFC 8032) using SHA-512.
+// This function is not part of the original Monocypher distribution; it is added by MicroSui
+// to provide compatibility with implementations that follow the standard SHA-512-based Ed25519.// It does NOT replace Monocypher's crypto_ed25519_sign (which uses BLAKE2b).
+// secret_key layout: seed[32] || public_key[32]
+// signature layout : R[32] || S[32]
+// Precondition: if message_size > 0, message must be non-NULL.
+void crypto_ed25519_sign_sha512(uint8_t signature[64],
+ const uint8_t secret_key[64],
+ const uint8_t *message,
+ size_t message_size)
+{
+ u8 a[64]; // a[0..31]=scalar (clamped), a[32..63]=prefix
+ u8 r64[64]; // full hash for r
+ u8 h64[64]; // full hash for h
+ u8 r[32];
+ u8 h[32];
+ u8 R[32];
+
+ crypto_sha512_ctx sha;
+
+ // 1) a || prefix = SHA512(seed); clamp(a)
+ crypto_sha512_init(&sha);
+ crypto_sha512_update(&sha, secret_key, 32); // seed
+ crypto_sha512_final(&sha, a);
+ crypto_eddsa_trim_scalar(a, a); // clamp first 32 bytes
+
+ // 2) r = SHA512(prefix || message) mod L
+ crypto_sha512_init(&sha);
+ crypto_sha512_update(&sha, a + 32, 32); // prefix
+ if (message_size) { crypto_sha512_update(&sha, message, message_size); }
+ crypto_sha512_final(&sha, r64);
+ crypto_eddsa_reduce(r, r64);
+
+ // 3) R = [r]B
+ crypto_eddsa_scalarbase(R, r);
+
+ // 4) h = SHA512(R || public_key || message) mod L
+ crypto_sha512_init(&sha);
+ crypto_sha512_update(&sha, R, 32);
+ crypto_sha512_update(&sha, secret_key + 32, 32); // public_key
+ if (message_size) { crypto_sha512_update(&sha, message, message_size); }
+ crypto_sha512_final(&sha, h64);
+ crypto_eddsa_reduce(h, h64);
+
+ // 5) S = (h * a + r) mod L; signature = R || S
+ COPY(signature, R, 32);
+ crypto_eddsa_mul_add(signature + 32, h, a, r);
+
+ // Wipe secrets
+ WIPE_CTX(&sha);
+ WIPE_BUFFER(a); WIPE_BUFFER(r64); WIPE_BUFFER(h64);
+ WIPE_BUFFER(r); WIPE_BUFFER(h); WIPE_BUFFER(R);
+
+ // Optional (defense-in-depth; enable in debug builds):
+ // #ifdef MICROSUI_STRICT
+ // u8 pk_chk[32];
+ // crypto_eddsa_scalarbase(pk_chk, a); // a[0..31] is the clamped scalar
+ // if (crypto_verify32(pk_chk, secret_key + 32)) {
+ // // Mismatched seed/public key; handle as you prefer (abort/log).
+ // }
+ // WIPE_BUFFER(pk_chk);
+ // #endif
+}
+
+// Ed25519 signature verification (pure / RFC 8032) using SHA-512.
+// This function is not part of the original Monocypher distribution; it is added by MicroSui
+// to provide compatibility with implementations that follow the standard SHA-512-based Ed25519.
+// It does NOT replace Monocypher's crypto_ed25519_check (which uses BLAKE2b).
+// public_key layout: A[32]
+// signature layout : R[32] || S[32]
+// Precondition: if msg_size > 0, msg must be non-NULL.
+int crypto_ed25519_check_sha512(const uint8_t signature[64],
+ const uint8_t public_key[32],
+ const uint8_t *msg,
+ size_t msg_size)
+{
+ u8 h_ram[32];
+ u8 hash[64];
+ crypto_sha512_ctx sha;
+
+ // h = SHA512(R || A || M) mod L
+ crypto_sha512_init(&sha);
+ crypto_sha512_update(&sha, signature, 32); // R
+ crypto_sha512_update(&sha, public_key, 32); // A
+ if (msg_size) { crypto_sha512_update(&sha, msg, msg_size); }
+ crypto_sha512_final(&sha, hash);
+
+ crypto_eddsa_reduce(h_ram, hash);
+
+ // Clean hash state
+ crypto_wipe(&sha, sizeof sha);
+ WIPE_BUFFER(hash);
+
+ // Check equation: [S]B = R + [h]A
+ return crypto_eddsa_check_equation(signature, public_key, h_ram);
+}
+
+
#ifdef MONOCYPHER_CPP_NAMESPACE
}
#endif
\ No newline at end of file
diff --git a/src/microsui_core/lib/monocypher/monocypher.h b/src/microsui_core/lib/monocypher/monocypher.h
index d4781a2..36b2b69 100644
--- a/src/microsui_core/lib/monocypher/monocypher.h
+++ b/src/microsui_core/lib/monocypher/monocypher.h
@@ -383,6 +383,16 @@ int crypto_ed25519_ph_check(const uint8_t signature [64],
const uint8_t public_key [32],
const uint8_t message_hash[64]);
+// Variants added by MicroSui
+void crypto_ed25519_sign_sha512(uint8_t signature[64],
+ const uint8_t secret_key[64],
+ const uint8_t *message,
+ size_t message_size);
+
+int crypto_ed25519_check_sha512(const uint8_t signature[64],
+ const uint8_t public_key[32],
+ const uint8_t *msg,
+ size_t msg_size);
#ifdef __cplusplus
}
diff --git a/src/microsui_core/sign.c b/src/microsui_core/sign.c
index 9fc38bf..8869b7b 100644
--- a/src/microsui_core/sign.c
+++ b/src/microsui_core/sign.c
@@ -5,9 +5,9 @@
#include
#include
#include
-#include "byte_conversions.h"
#include "lib/monocypher/monocypher.h"
-#include "lib/compact25519/compact_ed25519.h"
+
+#include "byte_conversions.h"
/**
* @brief Sign a Sui Transaction message using Ed25519 and produce a Sui-formatted signature.
@@ -16,10 +16,10 @@
* signs the digest with Ed25519, and encodes the result in the Sui signature
* format (scheme byte + 64-byte Ed25519 signature + 32-byte public key).
*
- * @param[out] sui_sig Output buffer for the Sui signature (must be 97 bytes).
- * @param[in] message Pointer to raw transaction bytes (already serialized).
- * @param[in] message_len Length of the transaction bytes.
- * @param[in] private_key 32-byte Ed25519 private key seed.
+ * @param[out] sui_sig_out Output buffer for the Sui signature (must be 97 bytes).
+ * @param[in] message Pointer to raw transaction bytes (already serialized).
+ * @param[in] message_len Length of the transaction bytes.
+ * @param[in] seed 32-byte Ed25519 private key seed.
*
* @return 0 on success, negative value on error.
*
@@ -27,15 +27,15 @@
* [0x00 scheme | 64-byte signature | 32-byte public key].
* @note This function is specific to the Ed25519 scheme.
*/
-int microsui_sign_ed25519(uint8_t sui_sig[97], const uint8_t* message, const size_t message_len, const uint8_t private_key[32]) {
- // 1. Copy private key to a local variable
- uint8_t private_key_cp[32];
- memcpy(private_key_cp, private_key, 32);
+int microsui_sign_ed25519(uint8_t sui_sig_out[97], const uint8_t* message, const size_t message_len, const uint8_t seed[32]) {
+ // 1. Copy seed to a local variable
+ uint8_t seed_cp[32];
+ memcpy(seed_cp, seed, 32);
// 2. Generate public and secret key
uint8_t public_key[32];
uint8_t secret_key[64];
- crypto_ed25519_key_pair(secret_key, public_key, private_key_cp);
+ crypto_ed25519_key_pair(secret_key, public_key, seed_cp);
// 3. Generate digest using BLAKE2b with the message with the intent
uint8_t digest[32];
@@ -49,17 +49,17 @@ int microsui_sign_ed25519(uint8_t sui_sig[97], const uint8_t* message, const siz
crypto_blake2b_final(&ctx, digest);
- // 4. Sign the digest using Ed25519 with the private key and public key
+ // 4. Sign the digest using Ed25519 with the secret key and public key
uint8_t ed25519_signature[64];
- compact_ed25519_sign(ed25519_signature, secret_key, digest, 32);
+ crypto_ed25519_sign_sha512(ed25519_signature, secret_key, digest, 32);
// 5. Build Sui signature
- sui_sig[0] = 0x00; // Ed25519 Scheme
- memcpy(sui_sig + 1, ed25519_signature, 64);
- memcpy(sui_sig + 65, public_key, 32);
+ sui_sig_out[0] = 0x00; // Ed25519 Scheme
+ memcpy(sui_sig_out + 1, ed25519_signature, 64);
+ memcpy(sui_sig_out + 65, public_key, 32);
crypto_wipe(secret_key, sizeof secret_key);
- crypto_wipe(private_key_cp, sizeof private_key_cp);
+ crypto_wipe(seed_cp, sizeof seed_cp);
crypto_wipe(&ctx, sizeof ctx);
crypto_wipe(digest, sizeof digest);
@@ -72,11 +72,11 @@ int microsui_sign_ed25519(uint8_t sui_sig[97], const uint8_t* message, const siz
* Dispatches to the appropriate signing routine depending on the provided
* scheme identifier. Currently only Ed25519 (0x00) is implemented.
*
- * @param[in] scheme Identifier of the signing scheme (0x00 = Ed25519).
- * @param[out] sui_sig Output buffer for the Sui signature (must be 97 bytes).
- * @param[in] message Pointer to the message/transaction bytes.
- * @param[in] message_len Length of the message in bytes.
- * @param[in] private_key 32-byte private key seed (scheme dependent).
+ * @param[out] sui_sig_out Output buffer for the Sui signature (must be 97 bytes).
+ * @param[in] scheme Identifier of the signing scheme (0x00 = Ed25519).
+ * @param[in] message Pointer to the message/transaction bytes.
+ * @param[in] message_len Length of the message in bytes.
+ * @param[in] seed 32-byte private key seed.
*
* @return 0 on success if scheme is supported,
* -1 if the scheme is not implemented or unsupported.
@@ -85,10 +85,10 @@ int microsui_sign_ed25519(uint8_t sui_sig[97], const uint8_t* message, const siz
* - 0x00: Ed25519 (implemented).
* - Others (Secp256k1, Secp256r1, Multisig, zkLogin, Passkey) are not yet implemented.
*/
-int microsui_sign(uint8_t scheme, uint8_t sui_sig[97], const uint8_t* message, const size_t message_len, const uint8_t private_key[32]) {
+int microsui_sign(uint8_t sui_sig_out[97], uint8_t scheme, const uint8_t* message, const size_t message_len, const uint8_t seed[32]) {
switch (scheme) {
case 0x00: // Pure Ed25519
- return microsui_sign_ed25519(sui_sig, message, message_len, private_key);
+ return microsui_sign_ed25519(sui_sig_out, message, message_len, seed);
case 0x01: // ECDSA Secp256k1
fprintf(stderr, "Error: ECDSA Secp256k1 signing is not implemented yet in MicroSui.\n");
return -1; // Not implemented
@@ -123,7 +123,8 @@ int microsui_sign(uint8_t scheme, uint8_t sui_sig[97], const uint8_t* message, c
* @param[in] message_len Length of the transaction bytes.
*
* @return 0 if the signature is valid,
- * -1 if the signature is invalid or the scheme byte is not Ed25519 (0x00).
+ * -1 if the scheme byte is not Ed25519 (0x00).
+ * -2 if the signature verification fails for a supported scheme
*
* @note The "intent" prefix used is {0x00, 0x00, 0x00}, matching the signing routine.
* @note This function does not recover a public key; it verifies using the public key
@@ -148,8 +149,73 @@ int microsui_verify_signature_ed25519(uint8_t sui_sig[97], const uint8_t* messag
crypto_blake2b_update(&ctx, message, message_len);
crypto_blake2b_final(&ctx, digest);
- if(compact_ed25519_verify(signature, public_key, digest, 32)) return 0;
- else return -1;
+ if(crypto_ed25519_check_sha512(signature, public_key, digest, 32) != 0) {
+ return -2; // Signature verification failed
+ }
+
+ return 0; // Signature is valid
+}
+
+/**
+ * @brief Verify a Sui-formatted Ed25519 signature and validate it against a known public key.
+ *
+ * Expects a Sui signature encoded as:
+ * [0x00 scheme | 64-byte Ed25519 signature | 32-byte public key]
+ *
+ * Rebuilds the Sui "message with intent" (prefix + tx bytes), digests it with
+ * BLAKE2b-256, verifies the Ed25519 signature using the public key embedded in
+ * the signature payload, and then confirms that the embedded public key matches
+ * the caller-supplied public key using a constant-time comparison.
+ *
+ * @param[in] sui_sig Pointer to the Sui signature buffer (must be 97 bytes).
+ * @param[in] message Pointer to raw transaction bytes (already serialized).
+ * @param[in] message_len Length of the transaction bytes.
+ * @param[in] public_key Pointer to the expected 32-byte Ed25519 public key.
+ *
+ * @return 0 if the signature is valid and the embedded public key matches @p public_key,
+ * -1 if the scheme byte is not Ed25519 (0x00),
+ * -2 if the signature verification fails,
+ * -3 if the public key embedded in the signature does not match @p public_key.
+ *
+ * @note The "intent" prefix used is {0x00, 0x00, 0x00}, matching the signing routine.
+ * @note The public key comparison is performed in constant time to mitigate timing attacks.
+ * @note Signature verification (-2) is checked before public key comparison (-3); a -3 result
+ * therefore implies the signature itself was cryptographically valid.
+ */
+
+int microsui_verify_signature_ed25519_with_public_key(uint8_t sui_sig[97], const uint8_t* message, const size_t message_len, uint8_t public_key[32]) {
+ if(sui_sig[0] != 0x00) {
+ return -1; // This is not an Ed25519 signature
+ }
+
+ uint8_t signature[64];
+ memcpy(signature, sui_sig + 1, 64);
+
+ uint8_t signature_public_key[32];
+ memcpy(signature_public_key, sui_sig + 65, 32);
+
+ uint8_t digest[32];
+ crypto_blake2b_ctx ctx;
+ crypto_blake2b_init(&ctx, 32);
+ const uint8_t intent[3] = {0x00, 0x00, 0x00};
+ crypto_blake2b_update(&ctx, intent, sizeof intent);
+ crypto_blake2b_update(&ctx, message, message_len);
+ crypto_blake2b_final(&ctx, digest);
+
+ if(crypto_ed25519_check_sha512(signature, signature_public_key, digest, 32) != 0) {
+ return -2; // Signature verification failed
+ }
+
+ // Check if the public key in the signature matches the provided public key (with timing attacks protection)
+ uint8_t diff = 0;
+ for (size_t i = 0; i < 32; i++) {
+ diff |= signature_public_key[i] ^ public_key[i];
+ }
+ if (diff != 0) {
+ return -3; // Public key mismatch
+ }
+
+ return 0; // Signature is valid and public key matches
}
/**
@@ -163,11 +229,16 @@ int microsui_verify_signature_ed25519(uint8_t sui_sig[97], const uint8_t* messag
* @param[in] message_len Length of the message in bytes.
*
* @return 0 if the signature is valid for the detected scheme,
- * -1 if the scheme is unsupported or verification fails.
+ * -1 if the scheme is unsupported or not implemented,
+ * -2 if the signature verification fails for a supported scheme
*
* @note Currently supported schemes:
- * - 0x00: Ed25519 (implemented).
- * - Others (Secp256k1, Secp256r1, Multisig, zkLogin, Passkey) are not yet implemented.
+ * - 0x00: Ed25519.
+ * @note Not yet implemented:
+ * - Secp256k1 (0x01), Secp256r1 (0x02), Multisig (0x03), zkLogin (0x05), Passkey (0x06).
+ * @see microsui_verify_signature_ed25519()
+ * @see microsui_verify_signature_with_public_key() for the variant that also
+ * validates the embedded public key against a caller-supplied expected key.
*/
int microsui_verify_signature(uint8_t sui_sig[97], const uint8_t* message, const size_t message_len) {
switch (sui_sig[0]) {
@@ -178,8 +249,44 @@ int microsui_verify_signature(uint8_t sui_sig[97], const uint8_t* message, const
}
}
+/**
+ * @brief Generic signature verification entry point with expected public key validation.
+ *
+ * Dispatches to the appropriate verification routine based on the scheme byte
+ * found in the provided Sui signature (sui_sig[0]), and additionally confirms
+ * that the public key embedded in the signature matches the caller-supplied key.
+ *
+ * @param[in] sui_sig Pointer to the Sui signature buffer (must be 97 bytes).
+ * @param[in] message Pointer to the message/transaction bytes (already serialized).
+ * @param[in] message_len Length of the message in bytes.
+ * @param[in] public_key Pointer to the expected 32-byte public key for the detected scheme.
+ *
+ * @return 0 if the signature is valid and the embedded public key matches @p public_key,
+ * -1 if the scheme byte is unsupported or not yet implemented,
+ * -2 if the signature verification fails for a supported scheme,
+ * -3 if the public key embedded in the signature does not match @p public_key.
+ *
+ * @note Currently supported schemes:
+ * - 0x00: Ed25519.
+ * @note Not yet implemented:
+ * - Secp256k1 (0x01), Secp256r1 (0x02), Multisig (0x03), zkLogin (0x05), Passkey (0x06).
+ * @note The public key comparison is delegated to the scheme-specific routine
+ * and performed in constant time to mitigate timing attacks.
+ * @see microsui_verify_signature_ed25519_with_public_key()
+ * @see microsui_verify_signature() for the variant that does not validate
+ * the embedded public key against an expected value.
+ */
+int microsui_verify_signature_with_public_key(uint8_t sui_sig[97], const uint8_t* message, const size_t message_len, uint8_t public_key[32]) {
+ switch (sui_sig[0]) {
+ case 0x00: // Ed25519
+ return microsui_verify_signature_ed25519_with_public_key(sui_sig, message, message_len, public_key);
+ default:
+ return -1; // Unsupported scheme
+ }
+}
+
-/// DEPRECATED FUNCTIONS ///
+/////////// DEPRECATED FUNCTIONS ///////////
/**
* @brief [DEPRECATED] Use microsui_sign() or microsui_sign_ed25519() instead.
*
@@ -187,20 +294,20 @@ int microsui_verify_signature(uint8_t sui_sig[97], const uint8_t* message, const
* Please use microsui_sign() or microsui_sign_ed25519(),
* which provide better compatibility and performance.
*
- * @param[out] sui_sig Output buffer for the Sui signature (must be 97 bytes).
+ * @param[out] sui_sig_out Output buffer for the Sui signature (must be 97 bytes).
* @param[in] message_hex Null-terminated string containing the full serialized tx message in hexa form.
- * @param[in] private_key 32-byte Ed25519 private key seed.
+ * @param[in] seed 32-byte Ed25519 private key seed.
*
* @return 0 on success, negative value on error.
*/
-int microsui_sign_message(uint8_t sui_sig[97], const char* message_hex, const uint8_t private_key[32]) {
+int microsui_sign_message(uint8_t sui_sig_out[97], const char* message_hex, const uint8_t seed[32]) {
// Convert the hex message to binary bytes
size_t msg_len = strlen(message_hex) / 2; // 2 hex chars = 1 byte
uint8_t* message = (uint8_t*)malloc(msg_len);
hex_to_bytes(message_hex, message, msg_len);
// Call the new ED25519 sign function version
- int res = microsui_sign_ed25519(sui_sig, message, msg_len, private_key);
+ int res = microsui_sign_ed25519(sui_sig_out, message, msg_len, seed);
free(message);
return res;
diff --git a/src/microsui_core/sign.h b/src/microsui_core/sign.h
index 38cc75f..26fbbdc 100644
--- a/src/microsui_core/sign.h
+++ b/src/microsui_core/sign.h
@@ -4,17 +4,21 @@
#include
#include
-int microsui_sign(uint8_t scheme, uint8_t sui_sig[97], const uint8_t* message, const size_t message_len, const uint8_t private_key[32]);
+int microsui_sign(uint8_t sui_sig_out[97], uint8_t scheme, const uint8_t* message, const size_t message_len, const uint8_t seed[32]);
-int microsui_sign_ed25519(uint8_t sui_sig[97], const uint8_t* message, const size_t message_len, const uint8_t private_key[32]);
+int microsui_sign_ed25519(uint8_t sui_sig_out[97], const uint8_t* message, const size_t message_len, const uint8_t seed[32]);
int microsui_verify_signature_ed25519(uint8_t sui_sig[97], const uint8_t* message, const size_t message_len);
+int microsui_verify_signature_ed25519_with_public_key(uint8_t sui_sig[97], const uint8_t* message, const size_t message_len, uint8_t public_key[32]);
+
int microsui_verify_signature(uint8_t sui_sig[97], const uint8_t* message, const size_t message_len);
+int microsui_verify_signature_with_public_key(uint8_t sui_sig[97], const uint8_t* message, const size_t message_len, uint8_t public_key[32]);
+
/**
* @deprecated Use microsui_sign() or microsui_sign_ed25519() instead.
*/
-int microsui_sign_message(uint8_t sui_sig[97], const char* message_hex, const uint8_t private_key[32]);
+int microsui_sign_message(uint8_t sui_sig_out[97], const char* message_hex, const uint8_t seed[32]);
#endif
\ No newline at end of file