Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
172 commits
Select commit Hold shift + click to select a range
0ce0958
feat: Updated crypto/segwit_addr to support bech32m encoding
muzaffarbhat07 Jul 29, 2025
ec842b8
feat: Added btc taproot address generation
muzaffarbhat07 Jul 29, 2025
4bef159
fix: Code formatting
muzaffarbhat07 Jul 29, 2025
6c4cd76
Merge pull request #665 from Cypherock/feat/btc-taproot/address
muzaffarbhat07 Aug 21, 2025
73c0395
feat(app): Add internal canton apis
prashantrahul141 Sep 12, 2025
5042a17
feat(app): Add canton app desc, empty entry point
prashantrahul141 Sep 12, 2025
aa04c53
feat(app): Register canton app, add to compilation pipeline
prashantrahul141 Sep 12, 2025
8e96b96
feat(app): Add canton_context.h with canton_config_t
prashantrahul141 Sep 13, 2025
eadcf98
feat(app): Add initial usb-event query parsing
prashantrahul141 Sep 13, 2025
7acff9f
feat(app): Add def for canton_txn_context_t
prashantrahul141 Sep 13, 2025
925ece9
feat(app): Add canton_txn.c
prashantrahul141 Sep 13, 2025
8301ce6
feat(app): Add canton 's name and lunit to canton
prashantrahul141 Sep 13, 2025
9be8ca1
feat(app): Add canton_get_query for internal canton api
prashantrahul141 Sep 13, 2025
43d4511
fix(app): Set canton's lunit to "CC"
prashantrahul141 Sep 15, 2025
d40c8fa
fix(app): Check `max_buffer_len` to be non-negative or zero
prashantrahul141 Sep 15, 2025
11e81ab
feat(app): Add prototype for static functions
prashantrahul141 Sep 15, 2025
b3612b0
feat(app): Add `handle_initiate_query` and `send_signature`
prashantrahul141 Sep 15, 2025
6f4c1b4
feat(app): Add `sign_txn` function implementation
prashantrahul141 Sep 15, 2025
87df9be
feat(app): Add unfinished `canton_unsigned_txn` struct
prashantrahul141 Sep 15, 2025
28814ff
feat(app): Add canton_txn_helpers with `canton_parse_transaction`
prashantrahul141 Sep 16, 2025
98ccd11
feat(app): Add `fetch_parse_txn_data` impl
prashantrahul141 Sep 16, 2025
274b459
feat: Add sia registrations
Keyur279 Sep 20, 2025
5190f42
feat: Update submodule for sia proto definition
Keyur279 Sep 20, 2025
1164b34
feat: Add proto-options for sia
Keyur279 Sep 22, 2025
49a1f32
feat: Add hyperliquid.c and hyperliquid.h to evm_family
0xcuriosity Sep 11, 2025
1b161b8
feat: Add hyperliquid.h to common/coin_support
0xcuriosity Sep 12, 2025
d17e8d5
feat: Add header file to common/core and change cmake
0xcuriosity Sep 13, 2025
bb25d30
feat: Fixed the id hyperliquid_app.c
0xcuriosity Sep 17, 2025
51cb073
feat: Fix formatting check errors
0xcuriosity Sep 17, 2025
818246a
feat: Fix format error
0xcuriosity Sep 23, 2025
ede5e62
feat: Fix include errors in core_flow_init.c
0xcuriosity Sep 23, 2025
c8a52d0
Merge branch 'develop' into feat/hyperliquid_support
0xcuriosity Sep 23, 2025
e51df99
feat: Changed app id in hyperliquid_app.c
0xcuriosity Sep 25, 2025
f8a938f
Merge remote-tracking branch 'origin/feat/hyperliquid_support' into h…
0xcuriosity Sep 25, 2025
5458187
feat: Add sia main and api
Sep 28, 2025
96bbfad
feat: Add constant texts and utils for sia
Sep 28, 2025
7e6a3cc
feat: Add sia context and helpers
Sep 28, 2025
14bbefb
feat: Add helpers and key derivations for sia
Sep 28, 2025
012e668
feat: Add mnemonic to seed derivation for sia
Sep 28, 2025
59a1ab4
feat: Add signing and verification for sia
Sep 29, 2025
5bb0544
feat: Taproot sign txn basic code
muzaffarbhat07 Aug 24, 2025
6a6215c
fix: Canton boilerplate code
muzaffarbhat07 Oct 7, 2025
f788ba0
feat: Added get pubkey functionality to canton app
muzaffarbhat07 Oct 8, 2025
ae137bb
fix: Code formatting
muzaffarbhat07 Oct 8, 2025
c3846f8
chore: Updated common submodule
muzaffarbhat07 Oct 8, 2025
a4fe6d0
Merge pull request #692 from Cypherock/feat/canton/pub-key
muzaffarbhat07 Oct 8, 2025
c1ea08a
Merge branch 'develop' into feat/hyperliquid_support
muzaffarbhat07 Oct 8, 2025
0d15e89
chore: Version bump
muzaffarbhat07 Oct 8, 2025
50573e4
feat: Added canton sign txn basic implementaion
muzaffarbhat07 Oct 9, 2025
5e1aeb8
fix: Input contract hash size
prashantrahul141 Oct 10, 2025
91ad7e9
feat: Add canton transaction encoding
prashantrahul141 Oct 10, 2025
640394d
fix: Use subfield not pointer for unsigned txn for context
prashantrahul141 Oct 10, 2025
e4e3a46
fix: Protobuf options for canton
prashantrahul141 Oct 12, 2025
5930644
fix: Potential memory leak in early return cases
prashantrahul141 Oct 12, 2025
a07c20b
fix: Early return when null parameter, pb_release
prashantrahul141 Oct 13, 2025
9c4a1fc
fix: Move user relevant info directly inside canton unsiged txn
prashantrahul141 Oct 13, 2025
e900c63
fix: Fixed size of 10 for input contract event blob
prashantrahul141 Oct 14, 2025
6810fa1
fix: Change sign curve to ed25519
prashantrahul141 Oct 14, 2025
ebd87b4
feat: Store receiver partyid and amount from exercise node chosen_value
prashantrahul141 Oct 14, 2025
9fa22b8
fix: Canton sign txn signature
muzaffarbhat07 Oct 14, 2025
a400046
fix: Canton sign txn memory leaks
muzaffarbhat07 Oct 14, 2025
9d5a4f3
fix: Review comments
muzaffarbhat07 Oct 14, 2025
fe24e59
Merge pull request #694 from Cypherock/feat/canton/sign-txn-encoding
muzaffarbhat07 Oct 14, 2025
fb99748
chore: Update common submodule
muzaffarbhat07 Oct 14, 2025
241a5df
Merge pull request #693 from Cypherock/feat/canton/sign-txn
muzaffarbhat07 Oct 14, 2025
083bd58
feat: Added canton sign topology txn basic code
muzaffarbhat07 Oct 13, 2025
ebffc19
feat: Added canton sign txn basic implementaion
muzaffarbhat07 Oct 9, 2025
c7df297
fix: Input contract hash size
prashantrahul141 Oct 10, 2025
d4d1b27
feat: Add canton transaction encoding
prashantrahul141 Oct 10, 2025
2cac5c1
fix: Use subfield not pointer for unsigned txn for context
prashantrahul141 Oct 10, 2025
099eac6
fix: Protobuf options for canton
prashantrahul141 Oct 12, 2025
13aabe1
fix: Potential memory leak in early return cases
prashantrahul141 Oct 12, 2025
aeea455
fix: Early return when null parameter, pb_release
prashantrahul141 Oct 13, 2025
3bbf802
fix: Move user relevant info directly inside canton unsiged txn
prashantrahul141 Oct 13, 2025
2e442e6
fix: Fixed size of 10 for input contract event blob
prashantrahul141 Oct 14, 2025
2db7bb2
fix: Change sign curve to ed25519
prashantrahul141 Oct 14, 2025
d550831
feat: Store receiver partyid and amount from exercise node chosen_value
prashantrahul141 Oct 14, 2025
11ea515
fix: Canton sign txn signature
muzaffarbhat07 Oct 14, 2025
88d1e99
fix: Canton sign txn memory leaks
muzaffarbhat07 Oct 14, 2025
2a57a57
fix: Review comments
muzaffarbhat07 Oct 14, 2025
9d65b6f
feat: Added canton helper functions, sign topology txn context
muzaffarbhat07 Oct 15, 2025
3349353
feat: Added canton sign topology txn function
muzaffarbhat07 Oct 15, 2025
43538d5
feat: Added canton sign topology txn protos
muzaffarbhat07 Oct 15, 2025
90a4a27
feat: Added canton sign topology txn encoding/hasing
muzaffarbhat07 Oct 15, 2025
2a00540
feat: Added canton sign topology txn functionality
muzaffarbhat07 Oct 15, 2025
a1fdda9
Merge branch 'feat/canton-support' into feat/canton/sign-topology-txn
muzaffarbhat07 Oct 15, 2025
43c9c96
Merge pull request #695 from Cypherock/feat/canton/sign-topology-txn
muzaffarbhat07 Oct 15, 2025
549b380
fix: Modified canton sign txn protos
muzaffarbhat07 Oct 15, 2025
76c5831
fix: Canton txn encoding
muzaffarbhat07 Oct 17, 2025
3c0cf11
feat: Parse canton transfer txn display info
muzaffarbhat07 Oct 17, 2025
dd50ddf
feat: Parse canton txn expiry time
muzaffarbhat07 Oct 17, 2025
8bce2c7
feat: Parse canton txn display info from choice txns
muzaffarbhat07 Oct 17, 2025
901d818
feat: Identify different types of canton txns
muzaffarbhat07 Oct 17, 2025
8defbd3
feat: Parse canton preapproval txn display info
muzaffarbhat07 Oct 17, 2025
7356a2a
fix: Show canton txn info as per txn type
muzaffarbhat07 Oct 17, 2025
eb10dbb
Merge pull request #689 from Cypherock/feat/hyperliquid_support
muzaffarbhat07 Oct 17, 2025
eaf1842
fix: Canton txn expiry
muzaffarbhat07 Nov 1, 2025
ff06740
Merge pull request #697 from Cypherock/fix/canton/sign-txn
muzaffarbhat07 Nov 1, 2025
8db7e3f
fix: Remove user verification from canton sign topology txn
muzaffarbhat07 Nov 1, 2025
b0e81a3
chore: Updated common submodule
muzaffarbhat07 Nov 3, 2025
5ae4ed0
chore: Version bump
muzaffarbhat07 Nov 3, 2025
c92dea8
fix: Remove unnecessary proto from topology txn proto
muzaffarbhat07 Nov 6, 2025
a685d71
feat: Validated topology txn restriction and participant permission
muzaffarbhat07 Nov 6, 2025
9324fd7
fix: Code formatting
muzaffarbhat07 Nov 6, 2025
29a4654
Merge pull request #698 from Cypherock/fix/canton/topology-txn-valida…
muzaffarbhat07 Nov 6, 2025
1224788
Merge branch 'develop' into feat/canton-support
muzaffarbhat07 Nov 6, 2025
d536ab5
fix: Max registry apps value
muzaffarbhat07 Nov 6, 2025
c9fc914
fix: Allow only one canton txn node
muzaffarbhat07 Nov 6, 2025
50fe01f
fix: Allow no canton input contract
muzaffarbhat07 Nov 6, 2025
0c9f2f5
fix: Parse only create node and transfer preapproval fields
muzaffarbhat07 Nov 6, 2025
f7592cb
fix: Withdraw user verification if not transfer preapproval
muzaffarbhat07 Nov 6, 2025
3095816
fix: Comment unused code to fix build issue
muzaffarbhat07 Nov 6, 2025
354d983
Merge pull request #699 from Cypherock/fix/canton/sign-txn-preapprova…
muzaffarbhat07 Nov 6, 2025
38719e6
chore: Version bump
muzaffarbhat07 Nov 6, 2025
7d49979
fix: Canton transfer preapproval flow
muzaffarbhat07 Nov 7, 2025
81b3530
chore: Version bump
muzaffarbhat07 Nov 7, 2025
7389af3
revert: Canton allow sign preapproval only
muzaffarbhat07 Nov 10, 2025
bb629f4
Merge pull request #700 from Cypherock/revert/canton/sign-txn-preappr…
muzaffarbhat07 Nov 10, 2025
5a984c1
feat: Canton sign enable utxo merge txn
muzaffarbhat07 Nov 10, 2025
435798b
Merge pull request #701 from Cypherock/feat/canton/utxo-merge
muzaffarbhat07 Nov 10, 2025
eeca7cf
chore: Version bump
muzaffarbhat07 Nov 10, 2025
b3976c0
fix: Canton txn ui
muzaffarbhat07 Nov 13, 2025
8ae431b
chore: Version bump
muzaffarbhat07 Nov 13, 2025
5ae4792
Merge branch 'develop' into feat/sia-support
Keyur279 Nov 18, 2025
f400e34
feat: Fix code formatting
Nov 18, 2025
f0b78d8
feat: Fix merge conflict and formatting
Nov 18, 2025
cc560ae
Merge pull request #683 from Cypherock/feat/canton-support
muzaffarbhat07 Nov 20, 2025
62576ee
feat: Sync with main and resolve conflicts
Nov 20, 2025
b880bc2
chore: Version bump
Nov 20, 2025
44ef3ce
feat(app): Base chain support under evm family
prashantrahul141 Oct 16, 2025
5a94789
feat: Added canton instruments
muzaffarbhat07 Nov 20, 2025
e06ec19
feat: Extract token txn data and instrument id
muzaffarbhat07 Nov 20, 2025
ece58f7
feat: Canton instrument whitelist check and verification by user
muzaffarbhat07 Nov 20, 2025
067a8ff
chore: Version bump
muzaffarbhat07 Nov 21, 2025
b71bc00
feat: Address sia code review feedback
Nov 21, 2025
7afd7cd
feat: Fix formatting issue
Nov 21, 2025
751adf7
feat: Fix import for ci
Nov 21, 2025
42d0847
feat: Fix review changes
Keyur279 Nov 23, 2025
68702c3
chore: Version bump
Nov 24, 2025
d7dbc66
Merge pull request #691 from Cypherock/feat/sia-support
muzaffarbhat07 Nov 24, 2025
ff09818
feat: Added canton usdc and usdcx instruments to whitelist
muzaffarbhat07 Dec 13, 2025
d0f5bd1
fix: Ui text sign token txn prompt
muzaffarbhat07 Dec 13, 2025
7f36889
Merge branch 'develop' into feat/canton/token-support
muzaffarbhat07 Dec 13, 2025
d23667f
chore: Version bump
muzaffarbhat07 Dec 13, 2025
23b48db
feat: Added canton sbc instrument to whitelist
muzaffarbhat07 Dec 15, 2025
e698e3c
Merge pull request #702 from Cypherock/feat/canton/token-support
muzaffarbhat07 Dec 15, 2025
dbab680
fix: Canton topology txns count
muzaffarbhat07 Dec 15, 2025
5640e47
Merge pull request #706 from Cypherock/fix/canton/toplogy-txn-new
muzaffarbhat07 Dec 15, 2025
c29bc04
fix: Remove instrument check from canton txn preapproval txn
muzaffarbhat07 Dec 15, 2025
71a1969
chore: Version bump
muzaffarbhat07 Dec 15, 2025
61a5cec
Merge pull request #705 from Cypherock/release/canton/token-etc
muzaffarbhat07 Dec 23, 2025
40239e6
feat(app): Hook base app to core flow and cmake
prashantrahul141 Oct 16, 2025
fea52b9
fix(app): Update app id to 16 for base
prashantrahul141 Oct 22, 2025
51a257d
feat: Common submodule update
prashantrahul141 Nov 24, 2025
7939e66
Merge branch 'develop' into feat/base-chain-support
muzaffarbhat07 Nov 24, 2025
a9bcc0e
chore: Version bump
Nov 25, 2025
91bb6a9
fix(core): Fix app's count in proto options
prashantrahul141 Dec 23, 2025
2c72d50
refactor: Remove unnecessary formatting in cmake
prashantrahul141 Dec 26, 2025
2958d15
fix: Btc taproot txn digest calculation
muzaffarbhat07 Dec 31, 2025
be421f3
feat: Validate taproot txn change address
muzaffarbhat07 Dec 31, 2025
940b375
Merge pull request #696 from Cypherock/feat/base-chain-support
muzaffarbhat07 Dec 31, 2025
0c613ae
chore: Version bump
muzaffarbhat07 Jan 2, 2026
d783549
fix: Taproot schnorr signature algo
muzaffarbhat07 Jan 2, 2026
03de199
fix: Code refactor
muzaffarbhat07 Jan 5, 2026
77aed95
fix: Code review
muzaffarbhat07 Jan 6, 2026
b46b898
Merge pull request #672 from Cypherock/feat/btc-taproot/sign-txn
muzaffarbhat07 Jan 6, 2026
c006754
Merge pull request #707 from Cypherock/release/base-support
muzaffarbhat07 Jan 6, 2026
016d791
Merge branch 'develop' into feat/btc-taproot/base
muzaffarbhat07 Jan 6, 2026
f05f484
fix: Remove unnecessary code
muzaffarbhat07 Jan 6, 2026
b046aee
chore: Version bump
muzaffarbhat07 Jan 7, 2026
bc6510b
Merge pull request #670 from Cypherock/feat/btc-taproot/base
muzaffarbhat07 Jan 27, 2026
c9fbd50
Merge branch 'main' into develop
muzaffarbhat07 Feb 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/btc_family/btc/btc_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ const btc_config_t btc_app = {
.legacy_xpub_ver = 0x0488b21e,
.segwit_xpub_ver = 0x049d7cb2,
.nsegwit_xpub_ver = 0x04b24746,
.taproot_xpub_ver = 0x04b24746,
.bech32_hrp = "bc",
.lunit_name = "BTC",
.name = "Bitcoin",
Expand Down
2 changes: 1 addition & 1 deletion apps/btc_family/btc_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ typedef struct {
uint32_t legacy_xpub_ver;
uint32_t segwit_xpub_ver;
uint32_t nsegwit_xpub_ver;

uint32_t taproot_xpub_ver;
/** The human-readable prefix for Bech32 encoded addresses. Applicable for
* Segwit and Taproot addresses. Ref:
* https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#segwit-address-format
Expand Down
184 changes: 184 additions & 0 deletions apps/btc_family/btc_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,18 @@

#include "btc_helpers.h"

#include <stdint.h>
#include <string.h>

#include "bignum.h"
#include "btc_priv.h"
#include "coin_utils.h"
#include "ecdsa.h"
#include "flash_config.h"
#include "secp256k1.h"
#include "segwit_addr.h"
#include "sha2.h"
#include "utils.h"

/*****************************************************************************
* EXTERN VARIABLES
Expand Down Expand Up @@ -95,6 +103,74 @@
* STATIC FUNCTIONS
*****************************************************************************/

// Computes sha256(tap_tweak_hash + tap_tweak_hash + x_only_public_key +
// root_hash) and stores the result in tweak_key_hash.
static bool bip340_tweak_key_hash(const uint8_t *x_only_public_key,
const uint8_t *root_hash,
uint8_t tweak_key_hash[32]) {
if (NULL == x_only_public_key || NULL == tweak_key_hash) {
return false;
}

size_t payload_size = 32; // x_only_public_key
if (root_hash != NULL) {
payload_size += 32;
}

uint8_t payload[payload_size];
memzero(payload, payload_size);
// Prepare the data for hashing
memcpy(payload, x_only_public_key, 32);
if (root_hash != NULL) {
memcpy(payload + 32, root_hash, 32);
}

bip340_tagged_hash("TapTweak", tweak_key_hash, payload, payload_size);
return true;
}

// Calculates result = (public_key_point + tweak_key_hash * G).x
static bool bip340_point_add_tweak(const ecdsa_curve *curve,
const uint8_t *public_key,
const uint8_t *tweak_key_hash,
uint8_t result[32]) {
if (NULL == public_key || NULL == tweak_key_hash || NULL == result) {
return false;
}

curve_point public_key_point = {0};
if (!ecdsa_read_pubkey(curve, public_key, &public_key_point)) {
return false;
}

// Negate y-coordinate if it's odd
if (bn_is_odd(&public_key_point.y)) {
bn_subtract(&curve->prime, &public_key_point.y, &public_key_point.y);
bn_mod(&public_key_point.y, &curve->prime);
}

bignum256 tweak_hash_bn = {0};
bn_read_be(tweak_key_hash, &tweak_hash_bn);
bn_mod(&tweak_hash_bn, &curve->order);

if (bn_is_zero(&tweak_hash_bn)) {
return false;
}

curve_point result_point = {0};
point_multiply(curve,
&tweak_hash_bn,
&curve->G,
&result_point); // result_point = tweak_hash_bn * G
point_add(curve,
&public_key_point,
&result_point); // result_point = public_key_point + result_point

// take the x-coordinate of the result point
bn_write_be(&result_point.x, result);
return true;
}

/*****************************************************************************
* GLOBAL FUNCTIONS
*****************************************************************************/
Expand Down Expand Up @@ -162,6 +238,9 @@ bool btc_get_version(uint32_t purpose_index, uint32_t *xpub_ver) {
case PURPOSE_NSEGWIT:
*xpub_ver = g_btc_app->nsegwit_xpub_ver;
break;
case PURPOSE_TAPROOT:
*xpub_ver = g_btc_app->taproot_xpub_ver;
break;
default:
status = false;
}
Expand Down Expand Up @@ -208,3 +287,108 @@ void format_value(const uint64_t value_in_sat,
snprintf(
msg, msg_len, "%0.*f %s", precision, fee_in_btc, g_btc_app->lunit_name);
}

// BIP340 tagged hash implementation
void bip340_tagged_hash(const char *tag,
uint8_t *out,
const uint8_t *data,
size_t data_len) {
uint8_t tag_hash[32];
Hasher hasher;

// Hash the tag
hasher_Init(&hasher, HASHER_SHA2);
hasher_Update(&hasher, (const uint8_t *)tag, strlen(tag));
hasher_Final(&hasher, tag_hash);

// tagged_hash = SHA256(SHA256(tag) || SHA256(tag) || data)
hasher_Init(&hasher, HASHER_SHA2);
hasher_Update(&hasher, tag_hash, 32);
hasher_Update(&hasher, tag_hash, 32);
hasher_Update(&hasher, data, data_len);
hasher_Final(&hasher, out);
}

// implementation of BIP-340 tweak public key for taproot without using
// secp256k1 library
bool bip340_tweak_public_key(const uint8_t *public_key,
const uint8_t *root_hash,
uint8_t *tweaked_public_key) {
if (NULL == public_key || NULL == tweaked_public_key) {
return false;
}

uint8_t tweak_key_hash[32] = {0};
if (!bip340_tweak_key_hash(public_key + 1, root_hash, tweak_key_hash)) {
return false;
}

if (!bip340_point_add_tweak(
&secp256k1, public_key, tweak_key_hash, tweaked_public_key)) {
return false;
}

return true;
}

// BIP341 private key tweaking for Taproot
bool bip340_tweak_private_key(const uint8_t *private_key,
const uint8_t *public_key,
const uint8_t *root_hash,
uint8_t *tweaked_private_key) {
if (NULL == private_key || NULL == tweaked_private_key) {
return false;
}

// Compute the tweak hash
uint8_t tweak_hash[32] = {0};
if (!bip340_tweak_key_hash(public_key + 1, root_hash, tweak_hash)) {
return false;
}

bignum256 sk = {0}, t = {0}, result = {0};
bn_read_be(private_key, &sk);
const ecdsa_curve *curve = &secp256k1;
curve_point public_key_point = {0};
if (!ecdsa_read_pubkey(curve, public_key, &public_key_point)) {
return false;
}

// Negate private key if public key y is odd
if (bn_is_odd(&public_key_point.y)) {
bn_subtract(&curve->order, &sk, &sk);
bn_mod(&sk, &curve->order);
}

// Compute tweaked private key: sk' = sk + t (mod n)
bn_read_be(tweak_hash, &t);
bn_mod(&t, &curve->order);
bn_copy(&sk, &result);
bn_add(&result, &t);
bn_mod(&result, &curve->order);

bn_write_be(&result, tweaked_private_key);

// Clear sensitive data
memzero(&sk, sizeof(sk));
memzero(&t, sizeof(t));
memzero(&result, sizeof(result));
memzero(tweak_hash, sizeof(tweak_hash));

return true;
}

int btc_get_taproot_address(uint8_t *public_key,
const char *hrp,
char *address) {
if (NULL == public_key || NULL == hrp || NULL == address) {
return 0;
}

uint8_t tweaked_public_key[32] = {0};
if (!bip340_tweak_public_key(public_key, NULL, tweaked_public_key)) {
return 0;
}

return segwit_addr_encode(address, hrp, 1, tweaked_public_key, 32);
}
69 changes: 69 additions & 0 deletions apps/btc_family/btc_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,73 @@ bool btc_derivation_path_guard(const uint32_t *path, uint32_t depth);
*/
void format_value(uint64_t value_in_sat, char *msg, size_t msg_len);

/**
* @brief Returns the taproot key path address string (Bech32M encoding)
* @details The functions assumes public key is compressed
*
* @param [in] public_key 33 Byte array representation of public key.
* @param [in] hrp HRP value for bech32M encoding "bc" for mainnet and
* "tb" for testnet.
* @param [out] address char array to store taproot address.
*
* @return 1 if successful and 0 if failure.
*/
int btc_get_taproot_address(uint8_t *public_key,
const char *hrp,
char *address);

/**
* @brief Tweaks a private key for Taproot key path spending.
* @details This function implements BIP341 private key tweaking for Taproot.
* The tweaked private key is computed as sk' = sk + t (mod n) where t is the
* tweak hash.
*
* @param private_key The internal private key (32 bytes)
* @param root_hash The Merkle root hash (32 bytes, can be NULL for key path
* only)
* @param public_key The public key (33 bytes, compressed format)
* @param tweaked_private_key Output buffer for the tweaked private key (32
* bytes)
*
* @return bool Status code
* @retval true Success
* @retval false Error (invalid inputs, tweaking failed)
*/
bool bip340_tweak_private_key(const uint8_t *private_key,
const uint8_t *public_key,
const uint8_t *root_hash,
uint8_t *tweaked_private_key);

/**
* @brief Tweaks a public key for Taproot key path spending.
* @details This function implements BIP341 public key tweaking for Taproot.
* The tweaked public key is computed as P' = P + t*G where t is the tweak hash.
*
* @param public_key The internal public key (33 bytes, compressed format)
* @param root_hash The Merkle root hash (32 bytes, can be NULL for key path
* only)
* @param tweaked_public_key Output buffer for the tweaked public key
* x-coordinate (32 bytes)
*
* @return bool Status code
* @retval true Success
* @retval false Error (invalid inputs, tweaking failed)
*/
bool bip340_tweak_public_key(const uint8_t *public_key,
const uint8_t *root_hash,
uint8_t *tweaked_public_key);

/**
* @brief BIP340 tagged hash implementation
* @details This function implements BIP340 tagged hash for Taproot.
*
* @param tag The tag to be hashed
* @param out The output buffer for the hashed data
* @param data The data to be hashed
* @param data_len The length of the data
*/
void bip340_tagged_hash(const char *tag,
uint8_t *out,
const uint8_t *data,
size_t data_len);
#endif
13 changes: 13 additions & 0 deletions apps/btc_family/btc_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ typedef struct {
uint8_t hash_outputs[32];
} btc_segwit_cache_t;

typedef struct {
bool filled;
uint8_t sha_prevouts[32];
uint8_t sha_amounts[32];
uint8_t sha_scriptpubkeys[32];
uint8_t sha_sequences[32];
uint8_t sha_outputs[32];
uint8_t sha_annex[32];
uint8_t sha_single_output[32];
} btc_taproot_cache_t;

typedef struct {
pb_byte_t prev_txn_hash[32];
uint32_t prev_output_index;
Expand Down Expand Up @@ -69,6 +80,8 @@ typedef struct {
btc_sign_txn_metadata_t metadata;
// Populated for segwit transactions
btc_segwit_cache_t segwit_cache;
// Populated for taproot transactions
btc_taproot_cache_t taproot_cache;

/**
* The structure holds the outputs (TxOut) of the transaction. Refer
Expand Down
6 changes: 4 additions & 2 deletions apps/btc_family/btc_pub_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ static size_t btc_get_address(const uint8_t *seed,
uint8_t *public_key,
char *address) {
HDNode node = {0};
char addr[50] = "";
char addr[70] = "";
size_t address_length = 0;

if (!derive_hdnode_from_path(
Expand Down Expand Up @@ -230,7 +230,9 @@ static size_t btc_get_address(const uint8_t *seed,
36);
break;

// TODO: add support for taproot
case PURPOSE_TAPROOT:
btc_get_taproot_address(node.public_key, g_btc_app->bech32_hrp, addr);
break;
default:
break;
}
Expand Down
12 changes: 11 additions & 1 deletion apps/btc_family/btc_script.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@

#include "base58.h"
#include "bip32.h"
#include "btc_helpers.h"
#include "btc_priv.h"
#include "memzero.h"
#include "ripemd160.h"
Expand Down Expand Up @@ -240,12 +241,21 @@ bool btc_check_script_address(const uint8_t *script,
uint8_t digest[HASHER_DIGEST_LENGTH] = {0};
btc_script_type_e type = btc_get_script_type(script, script_len);
if (SCRIPT_TYPE_P2PKH != type && SCRIPT_TYPE_P2WPKH != type &&
SCRIPT_TYPE_P2SH != type) {
SCRIPT_TYPE_P2SH != type && SCRIPT_TYPE_P2TR != type) {
// allow only p2pkh and p2wpkh and p2sh-p2wpkh for change output
return false;
}
uint8_t offset = (SCRIPT_TYPE_P2PKH == type) ? 3 : 2;

if (SCRIPT_TYPE_P2TR == type) {
offset = 2;
uint8_t tweaked_public_key[32] = {0};
if (!bip340_tweak_public_key(public_key, NULL, tweaked_public_key)) {
return false;
}
return memcmp(tweaked_public_key, script + offset, 32) == 0;
}

hasher_Raw(HASHER_SHA2_RIPEMD, public_key, BTC_SHORT_PUB_KEY_SIZE, digest);

if (SCRIPT_TYPE_P2SH == type) {
Expand Down
Loading
Loading