Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): add Zcash Rust primitives #2510

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Conversation

krnak
Copy link
Contributor

@krnak krnak commented Sep 12, 2022

This PR adds

  • pasta curves arithmetic (from pasta_curves crate)
  • redpallas signature scheme (from reddsa crate)
  • poseidon hash function (my own tested implementation)

Implementation details

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

Crate pasta_curves is patched, because these issue and pr are pending:

Related links:

@krnak krnak force-pushed the zcash-rust-primitives branch from 30ab596 to 8715425 Compare September 12, 2022 14:00
@prusnak
Copy link
Member

prusnak commented Sep 12, 2022

It would be great if you introduced FEATURE_FLAGS["ZCASH_SHIELDED"] so we could easily turn on/off the feature

@krnak krnak mentioned this pull request Sep 15, 2022
7 tasks
@krnak
Copy link
Contributor Author

krnak commented Sep 19, 2022

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.

@krnak krnak force-pushed the zcash-rust-primitives branch from 109f81a to 385157e Compare September 20, 2022 12:23
@prusnak
Copy link
Member

prusnak commented Sep 21, 2022

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:

rf"-e 's/utils\.BITCOIN_ONLY/{btc_only}/g'",

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?

Screenshot 2022-09-21 at 13 13 39

@krnak
Copy link
Contributor Author

krnak commented Sep 29, 2022

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.

@andrewkozlik
Copy link
Contributor

I made changes suggested by @prusnak , but I'm still getting ERROR: Altcoin strings found in Bitcoin-only firmware..

178d06b 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?

Screenshot 2022-09-21 at 13 13 39

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.

@krnak
Copy link
Contributor Author

krnak commented Oct 7, 2022

thank you andrew

@andrewkozlik
Copy link
Contributor

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: 017bb4f.

@prusnak
Copy link
Member

prusnak commented Oct 7, 2022

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.

@matejcik
Copy link
Contributor

istm we could keep ZCASH_SHIELDED qstr only for emulator build?
device build is always frozen so the fixed bool replacement is always applied

Copy link
Contributor

@matejcik matejcik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review is here.

Before merging, we will also need to do at least a brief review of the pulled in dependencies.

core/embed/extmod/modtrezorutils/modtrezorutils.c Outdated Show resolved Hide resolved
core/embed/rust/blake2b_hal/src/lib.rs Outdated Show resolved Hide resolved
impl<const N: usize> TryFrom<Obj> for [u8; N] {
type Error = Error;

fn try_from(obj: Obj) -> Result<[u8; N], Error> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: we have removed the Buffer type so this will need to be redone in terms of get_buffer().

istm it's gonna be trivially Ok(unsafe { get_buffer(obj) }.try_into()?) with the appropriate SAFETY comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok . I suggest resolving this after squashing and rebasing

core/embed/rust/src/micropython/wrap.rs Outdated Show resolved Hide resolved
core/embed/rust/src/zcash_primitives/pallas/common.rs Outdated Show resolved Hide resolved
core/embed/rust/src/zcash_primitives/pallas/generators.rs Outdated Show resolved Hide resolved
core/embed/rust/src/zcash_primitives/pallas/scalar.rs Outdated Show resolved Hide resolved
core/embed/rust/src/zcash_primitives/pallas/point.rs Outdated Show resolved Hide resolved
core/embed/rust/src/zcash_primitives/pallas/scalar.rs Outdated Show resolved Hide resolved
@krnak krnak force-pushed the zcash-rust-primitives branch from 23beeec to e73a02a Compare November 16, 2022 12:48
@krnak krnak force-pushed the zcash-rust-primitives branch from e73a02a to 6311675 Compare November 16, 2022 12:50
@matejcik
Copy link
Contributor

Tentative approve, pending review of the Rust dependencies.

@str4d
Copy link
Contributor

str4d commented Dec 6, 2022

@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.

@krnak
Copy link
Contributor Author

krnak commented Dec 6, 2022

Yes, I confirm. The only thing I need to be patched in pasta_curves is alloc-free hash-to-curve implementation.

@Hannsek Hannsek added the blocked Blocked by external force. Third party inputs required. label Apr 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked Blocked by external force. Third party inputs required.
Projects
Status: 🔎 Needs review
Development

Successfully merging this pull request may close these issues.

7 participants