trezor-firmware
trezor-firmware copied to clipboard
feat(core): add Zcash Rust primitives
This PR adds
- pasta curves arithmetic (from
pasta_curvescrate) - redpallas signature scheme (from
reddsacrate) - poseidon hash function (my own tested implementation)
Three pasta curves struct (Fp, Scalar and Point) are exposed to micropython using generic container Wrapped<T> defined in micropython/wrap.rs.
Newly imported crates depend on blake2b_simd crate. Since there is already a C implementation of blake2b, I just added a Rust interface to it (in rust/blake2b_hal) and then I overwrote blake2b_simd by blake2b_hal via [crates-io.patch].
Poseidon function requires some precomputed round constants. Since the generating algorithm is pretty lightweight (it is based on LSFR), I decided to replace the constants table (6144 bytes) by my own highly optimized implementation of the generator itself (circa 512 kb). Generator is tested on all expected constants. Poseidon implementation is tested on official zcash test vectors.
Crate reddsa is patched to include this minor fix
- https://github.com/ZcashFoundation/reddsa/pull/28
Crate pasta_curves is patched, because these issue and pr are pending:
- https://github.com/zcash/pasta_curves/issues/46
- https://github.com/zcash/pasta_curves/pull/47
Related links:
- pasta curves crate
- reddsa crate
- Poseidon specification
- Poseidon Orchard instantiation (§5.4.1.10)
- Poseidon reference implementation - python
- Poseidon reference implementation - Rust (quite more general)
It would be great if you introduced FEATURE_FLAGS["ZCASH_SHIELDED"] so we could easily turn on/off the feature
How to deal with this ? @prusnak
ZCASH_SHIELDED
ERROR: Altcoin strings found in Bitcoin-only firmware.
I will need this flag to be accessible from python to disable some functionalities in module zcash/signer.py.
I will need this flag to be accessible from python to disable some functionalities in module
zcash/signer.py.
We need to replace utils.ZCASH_SHIELDED with a True/False literal, similarly to what we do here:
https://github.com/trezor/trezor-firmware/blob/4bed278e80d23077676128eba8cb2478fcd31120/core/site_scons/site_tools/micropython/init.py#L31
Maybe this does the trick?
diff --git a/core/SConscript.firmware b/core/SConscript.firmware
index 96ffec17d..3d0d30cb4 100644
--- a/core/SConscript.firmware
+++ b/core/SConscript.firmware
@@ -678,7 +678,7 @@ if FROZEN:
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/bitcoin/sign_tx/zcash_v4.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/enums/Zcash*.py'))
- source_mpy = env.FrozenModule(source=SOURCE_PY, source_dir=SOURCE_PY_DIR, bitcoin_only=BITCOIN_ONLY)
+ source_mpy = env.FrozenModule(source=SOURCE_PY, source_dir=SOURCE_PY_DIR, bitcoin_only=BITCOIN_ONLY, zcash_shielded=FEATURE_FLAGS['ZCASH_SHIELDED'])
source_mpyc = env.FrozenCFile(
target='frozen_mpy.c', source=source_mpy, qstr_header=qstr_preprocessed)
diff --git a/core/site_scons/site_tools/micropython/__init__.py b/core/site_scons/site_tools/micropython/__init__.py
index 38c40880f..8f897a3ca 100644
--- a/core/site_scons/site_tools/micropython/__init__.py
+++ b/core/site_scons/site_tools/micropython/__init__.py
@@ -26,9 +26,11 @@ def generate(env):
# replace "utils.BITCOIN_ONLY" with literal constant (True/False)
# so the compiler can optimize out the things we don't want
btc_only = env['bitcoin_only'] == '1'
+ zcash_shielded = env['zcash_shielded'] == '1'
interim = f"{target[:-4]}.i" # replace .mpy with .i
sed_scripts = " ".join([
rf"-e 's/utils\.BITCOIN_ONLY/{btc_only}/g'",
+ rf"-e 's/utils\.ZCASH_SHIELDED/{zcash_shielded}/g'",
r"-e 's/if TYPE_CHECKING/if False/'",
r"-e 's/import typing/# \0/'",
r"-e '/from typing import (/,/^\s*)/ {s/^/# /}'",
If we do the change above I guess we can drop this change completely? Not sure if that's what we want or we want to add exception for this to the check. Maybe @matejcik can help?
I made changes suggested by @prusnak , but I'm still getting ERROR: Altcoin strings found in Bitcoin-only firmware..
I isolated all new code by ZCASH_SHIELDED flag and tried to define this flag. Since I'm not a creator of TT flag system, neither bitcoin-only edition, resolving this issue could take me hours. I would appreciate if I could let this issue up to you.
I made changes suggested by @prusnak , but I'm still getting
ERROR: Altcoin strings found in Bitcoin-only firmware..
178d06b597134cc3f7fd81ada1be9952d2dc4c19 should fix it.
If we do the change above I guess we can drop this change completely? Not sure if that's what we want or we want to add exception for this to the check. Maybe @matejcik can help?
![]()
I dropped the QSTR, which means that from trezorutils import ZCASH_SHIELDED is importing something that doesn't exist, but it's only for TYPE_CHECKING, so that seems OK. It seems cleaner than adding an exception to tools/check-bitcoin-only.
thank you andrew
178d06b should fix it.
Darn, I hadn't realized this would break the unit tests:
File "../src/trezor/crypto/hashlib.py", line 16, in <module>
AttributeError: 'module' object has no attribute 'ZCASH_SHIELDED'
I think there is no way around that, is there? Adding an exception to tools/check-bitcoin-only: https://github.com/trezor/trezor-firmware/pull/2510/commits/017bb4f54d8f189d2fef01b96f0f1204e3d8583c.
I think there is no way around that, is there? Adding an exception to
tools/check-bitcoin-only: 017bb4f.
Yeah, I guess 017bb4f is the best way how we can fix this.
istm we could keep ZCASH_SHIELDED qstr only for emulator build?
device build is always frozen so the fixed bool replacement is always applied
Tentative approve, pending review of the Rust dependencies.
@jarys just to clarify, the only thing you need patched into pasta_curves for this PR is the alloc-free hash-to-curve implementation? If so, I'll try and find some time to work on it.
Yes, I confirm. The only thing I need to be patched in pasta_curves is alloc-free hash-to-curve implementation.