Skip to content

Commit

Permalink
feat(core): add support for Zcash unified addresses
Browse files Browse the repository at this point in the history
  • Loading branch information
krnak committed Jul 8, 2022
1 parent b9e2ca9 commit ee68a69
Show file tree
Hide file tree
Showing 29 changed files with 605 additions and 79 deletions.
17 changes: 17 additions & 0 deletions common/protob/messages-zcash.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
syntax = "proto2";
package hw.trezor.messages.zcash;

// Sugar for easier handling in Java
option java_package = "com.satoshilabs.trezor.lib.protobuf";
option java_outer_classname = "TrezorMessageZcash";

/**
* Receiver typecodes for unified addresses.
* see: https://zips.z.cash/zip-0316#encoding-of-unified-addresses
*/
enum ZcashReceiverTypecode {
P2PKH = 0;
P2SH = 1;
SAPLING = 2;
ORCHARD = 3;
}
1 change: 1 addition & 0 deletions core/.changelog.d/2371.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add support for Zcash unified addresses
14 changes: 11 additions & 3 deletions core/SConscript.firmware
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import os

BITCOIN_ONLY = ARGUMENTS.get('BITCOIN_ONLY', '0')
EVERYTHING = BITCOIN_ONLY != '1'
USE_ZCASH = BITCOIN_ONLY == '1' # Zcash parasitizes on BITCOIN_ONLY free memory
TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T')
UI2 = ARGUMENTS.get('UI2', '0') == '1' or TREZOR_MODEL in ('1', 'R')

Expand Down Expand Up @@ -198,6 +199,10 @@ SOURCE_MOD += [
SOURCE_MOD += [
'embed/extmod/rustmods/modtrezorproto.c',
]
if USE_ZCASH:
SOURCE_MOD += [
'embed/extmod/rustmods/modtrezororchardlib.c',
]
if UI2:
SOURCE_MOD += [
'embed/extmod/rustmods/modtrezorui2.c',
Expand Down Expand Up @@ -417,7 +422,7 @@ if FEATURE_FLAGS["SYSTEM_VIEW"]:

SOURCE_QSTR = SOURCE_MOD + SOURCE_MICROPYTHON + SOURCE_MICROPYTHON_SPEED

env = Environment(ENV=os.environ, CFLAGS='%s -DPRODUCTION=%s -DPYOPT=%s -DBITCOIN_ONLY=%s' % (ARGUMENTS.get('CFLAGS', ''), ARGUMENTS.get('PRODUCTION', '0'), PYOPT, BITCOIN_ONLY))
env = Environment(ENV=os.environ, CFLAGS='%s -DPYOPT=%s -DBITCOIN_ONLY=%s -DUSE_ZCASH=%s' % (ARGUMENTS.get('CFLAGS', ''), PYOPT, BITCOIN_ONLY, '1' if USE_ZCASH else '0'))

env.Tool('micropython')

Expand Down Expand Up @@ -668,13 +673,14 @@ if FROZEN:
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/tezos/*.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/enums/Tezos*.py'))

SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/zcash/*.py'))

SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/webauthn/*.py'))

SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/decred.py'))

if EVERYTHING or USE_ZCASH:
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/bitcoinlike.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/zcash_v4.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/zcash/*.py'))

source_mpy = env.FrozenModule(source=SOURCE_PY, source_dir=SOURCE_PY_DIR, bitcoin_only=BITCOIN_ONLY)

Expand Down Expand Up @@ -712,6 +718,8 @@ def cargo_build():
profile = ''

features = ['micropython', 'protobuf', f'model_t{TREZOR_MODEL.lower()}']
if USE_ZCASH:
features.append('use_zcash')
if BITCOIN_ONLY == '1':
features.append('bitcoin_only')
if UI2:
Expand Down
14 changes: 11 additions & 3 deletions core/SConscript.unix
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import os

BITCOIN_ONLY = ARGUMENTS.get('BITCOIN_ONLY', '0')
EVERYTHING = BITCOIN_ONLY != '1'
USE_ZCASH = True
TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T')
UI2 = ARGUMENTS.get('UI2', '0') == '1' or TREZOR_MODEL in ('1', 'R')

Expand Down Expand Up @@ -198,6 +199,10 @@ SOURCE_MOD += [
SOURCE_MOD += [
'embed/extmod/rustmods/modtrezorproto.c',
]
if USE_ZCASH:
SOURCE_MOD += [
'embed/extmod/rustmods/modtrezororchardlib.c',
]
if UI2:
SOURCE_MOD += [
'embed/extmod/rustmods/modtrezorui2.c',
Expand Down Expand Up @@ -363,7 +368,7 @@ if PYOPT == '0' or not FROZEN:
else:
STATIC=""

env = Environment(ENV=os.environ, CFLAGS='%s -DPYOPT=%s -DBITCOIN_ONLY=%s %s' % (ARGUMENTS.get('CFLAGS', ''), PYOPT, BITCOIN_ONLY, STATIC))
env = Environment(ENV=os.environ, CFLAGS='%s -DPYOPT=%s -DBITCOIN_ONLY=%s -DUSE_ZCASH=%s %s' % (ARGUMENTS.get('CFLAGS', ''), PYOPT, BITCOIN_ONLY, '1' if USE_ZCASH else '0', STATIC))

env.Tool('micropython')

Expand Down Expand Up @@ -624,13 +629,14 @@ if FROZEN:
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/tezos/*.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/enums/Tezos*.py'))

SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/zcash/*.py'))

SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/webauthn/*.py'))

SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/decred.py'))

if EVERYTHING or USE_ZCASH:
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/bitcoinlike.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/zcash_v4.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/zcash/*.py'))

source_mpy = env.FrozenModule(source=SOURCE_PY, source_dir=SOURCE_PY_DIR, bitcoin_only=BITCOIN_ONLY)

Expand Down Expand Up @@ -666,6 +672,8 @@ RUST_LIBPATH = f'{RUST_LIBDIR}/lib{RUST_LIB}.a'

def cargo_build():
features = ['micropython', 'protobuf', f'model_t{TREZOR_MODEL.lower()}']
if USE_ZCASH:
features.append('use_zcash')
if BITCOIN_ONLY == '1':
features.append('bitcoin_only')
if UI2:
Expand Down
6 changes: 6 additions & 0 deletions core/embed/extmod/modtrezorutils/modtrezorutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ STATIC mp_obj_str_t mod_trezorutils_revision_obj = {
/// MODEL: str
/// EMULATOR: bool
/// BITCOIN_ONLY: bool
/// USE_ZCASH: bool
/// FIRMWARE_SECTORS_COUNT: int

STATIC const mp_rom_map_elem_t mp_module_trezorutils_globals_table[] = {
Expand Down Expand Up @@ -316,6 +317,11 @@ STATIC const mp_rom_map_elem_t mp_module_trezorutils_globals_table[] = {
#else
{MP_ROM_QSTR(MP_QSTR_BITCOIN_ONLY), mp_const_false},
#endif
#if USE_ZCASH
{MP_ROM_QSTR(MP_QSTR_USE_ZCASH), mp_const_true},
#else
{MP_ROM_QSTR(MP_QSTR_USE_ZCASH), mp_const_false},
#endif
};

STATIC MP_DEFINE_CONST_DICT(mp_module_trezorutils_globals,
Expand Down
54 changes: 54 additions & 0 deletions core/embed/extmod/rustmods/modtrezororchardlib.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "py/runtime.h"

#if USE_ZCASH

#include "librust.h"

/// def f4jumble(message: bytearray) -> None:
/// """Mutates a message by F4Jumble permutation."""
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_orchardlib_f4jumble, orchardlib_f4jumble);

/// def f4jumble_inv(message: bytearray) -> None:
/// """Mutates a message by F4Jumble inverse permutation."""
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_orchardlib_f4jumble_inv,
orchardlib_f4jumble_inv);

STATIC const mp_rom_map_elem_t mp_module_trezororchardlib_globals_table[] = {
{MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_trezororchardlib)},
{MP_ROM_QSTR(MP_QSTR_f4jumble), MP_ROM_PTR(&mod_orchardlib_f4jumble)},
{MP_ROM_QSTR(MP_QSTR_f4jumble_inv),
MP_ROM_PTR(&mod_orchardlib_f4jumble_inv)},

};

STATIC MP_DEFINE_CONST_DICT(mp_module_trezororchardlib_globals,
mp_module_trezororchardlib_globals_table);

const mp_obj_module_t mp_module_trezororchardlib = {
.base = {&mp_type_module},
.globals = (mp_obj_dict_t *)&mp_module_trezororchardlib_globals,
};

MP_REGISTER_MODULE(MP_QSTR_trezororchardlib, mp_module_trezororchardlib,
USE_ZCASH);

#endif // USE_ZCASH
39 changes: 39 additions & 0 deletions core/embed/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion core/embed/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ model_t1 = ["buttons"]
model_tr = ["buttons"]
micropython = []
protobuf = ["micropython"]
use_zcash = ["micropython", "f4jumble"]
ui = []
ui_debug = []
buttons = []
touch = []
clippy = []
test = ["cc", "glob", "micropython", "protobuf", "ui", "ui_debug"]
test = ["cc", "glob", "micropython", "protobuf", "use_zcash", "ui", "ui_debug"]

[lib]
crate-type = ["staticlib"]
Expand Down Expand Up @@ -49,6 +50,11 @@ default_features = false
version = "0.2.4"
default_features = false

[dependencies.f4jumble]
version = "0.1.0"
default-features = false
optional = true

# Build dependencies

[build-dependencies.bindgen]
Expand Down
6 changes: 6 additions & 0 deletions core/embed/rust/librust.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,9 @@ extern mp_obj_module_t mp_module_trezorui2;
#ifdef TREZOR_EMULATOR
mp_obj_t ui_debug_layout_type();
#endif

// Zcash
#if USE_ZCASH
mp_obj_t orchardlib_f4jumble(mp_obj_t message);
mp_obj_t orchardlib_f4jumble_inv(mp_obj_t message);
#endif
2 changes: 2 additions & 0 deletions core/embed/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ mod error;
#[cfg(feature = "micropython")]
#[macro_use]
mod micropython;
#[cfg(feature = "use_zcash")]
mod orchardlib;
#[cfg(feature = "protobuf")]
mod protobuf;
mod time;
Expand Down
36 changes: 36 additions & 0 deletions core/embed/rust/src/orchardlib/f4jumble_bridge.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//! This module is a python FFI bridge for f4jumble crate.

use core::ops::DerefMut;
use f4jumble;

use crate::error::Error;
use crate::micropython::{buffer::BufferMut, obj::Obj, util};

// Length of F4jumbled message must be in range 48..=4194368.
impl From<f4jumble::Error> for Error {
fn from(_e: f4jumble::Error) -> Error {
Error::OutOfRange
}
}

/// Apply the F4jumble permutation to a message.
#[no_mangle]
pub extern "C" fn orchardlib_f4jumble(message: Obj) -> Obj {
let block = || {
let mut message: BufferMut = message.try_into()?;
f4jumble::f4jumble_mut(message.deref_mut())?;
Ok(Obj::const_none())
};
unsafe { util::try_or_raise(block) }
}

/// Apply the F4jumble inverse permutation to a message.
#[no_mangle]
pub extern "C" fn orchardlib_f4jumble_inv(message: Obj) -> Obj {
let block = || {
let mut message: BufferMut = message.try_into()?;
f4jumble::f4jumble_inv_mut(message.deref_mut())?;
Ok(Obj::const_none())
};
unsafe { util::try_or_raise(block) }
}
1 change: 1 addition & 0 deletions core/embed/rust/src/orchardlib/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mod f4jumble_bridge;
11 changes: 11 additions & 0 deletions core/mocks/generated/trezororchardlib.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from typing import *


# extmod/rustmods/modtrezororchardlib.c
def f4jumble(message: bytearray) -> None:
"""Mutates a message by F4Jumble permutation."""


# extmod/rustmods/modtrezororchardlib.c
def f4jumble_inv(message: bytearray) -> None:
"""Mutates a message by F4Jumble inverse permutation."""
1 change: 1 addition & 0 deletions core/mocks/generated/trezorutils.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,5 @@ VERSION_PATCH: int
MODEL: str
EMULATOR: bool
BITCOIN_ONLY: bool
USE_ZCASH: bool
FIRMWARE_SECTORS_COUNT: int
4 changes: 4 additions & 0 deletions core/src/all_modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,8 @@
import trezor.enums.TezosBallotType
trezor.enums.TezosContractType
import trezor.enums.TezosContractType
trezor.enums.ZcashReceiverTypecode
import trezor.enums.ZcashReceiverTypecode
trezor.ui.components.common.webauthn
import trezor.ui.components.common.webauthn
trezor.ui.components.tt.webauthn
Expand Down Expand Up @@ -775,6 +777,8 @@
import apps.webauthn.resident_credentials
apps.zcash
import apps.zcash
apps.zcash.addresses
import apps.zcash.addresses
apps.zcash.hasher
import apps.zcash.hasher
apps.zcash.signer
Expand Down
Loading

0 comments on commit ee68a69

Please sign in to comment.