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

Zcash shielded transactions #2472

Draft
wants to merge 74 commits into
base: zcash-rust-primitives
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 59 commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
ac73bfa
feat(core): add Zcash shielded transactions
krnak Nov 17, 2022
dc2057d
refactor(core): move Zcash generators module to Rust
krnak Nov 17, 2022
37aed5d
fixup! refactor(core): move Zcash generators module to Rust
krnak Nov 17, 2022
f1a90fc
feat(core): move Orchard parameters into a separate message
krnak Nov 17, 2022
ff90b39
fixup! feat(core): add Zcash shielded transactions
krnak Nov 17, 2022
2dcdb57
fixup! feat(core): add Zcash shielded transactions
krnak Nov 17, 2022
b9e5a4c
fixup! feat(core): add Zcash shielded transactions
krnak Nov 17, 2022
e9f7629
fixup! feat(core): add Zcash shielded transactions
krnak Nov 17, 2022
d4fc75e
fixup! feat(core): add Zcash shielded transactions
krnak Nov 17, 2022
f9658af
fixup! feat(core): add Zcash shielded transactions
krnak Nov 17, 2022
0b27fe7
fixup! feat(core): add Zcash shielded transactions
krnak Nov 17, 2022
8bddb42
fixup! feat(core): add Zcash shielded transactions
krnak Nov 17, 2022
8384dc6
fixup! feat(core): add Zcash shielded transactions
krnak Nov 17, 2022
6d1addd
fixup! feat(core): add Zcash shielded transactions
krnak Nov 17, 2022
991a6e5
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
44f3739
fix(core): fix syntax
krnak Nov 18, 2022
08b5590
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
2ec051f
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
398c0f8
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
b1632b8
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
389e5b3
feat(core): optimize memory usage
krnak Nov 18, 2022
758d4dc
feat(core): optimize memory usage 2
krnak Nov 18, 2022
ca89b1e
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
34cb96d
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
5c615ec
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
0b0eee0
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
98c0f06
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
e00744f
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
bb500a3
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
0ca4bfc
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
0299f67
refactor(core): replace all `@staticmethod`s by `@classmethod`s
krnak Nov 18, 2022
aabe15a
fixup! refactor(core): replace all `@staticmethod`s by `@classmethod`s
krnak Nov 18, 2022
1aafe9b
refactor(core): don't copy ZcashOrchardParams in Orchard signer
krnak Nov 18, 2022
a8f2631
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
099c4eb
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
f351e77
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
8e96165
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
145c183
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
05efbd8
style: make style
krnak Nov 18, 2022
99e3384
refactor(core): always use `utils.` namespace for `ZCASH_SHIELDED`
krnak Nov 18, 2022
821d0e2
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
15f561c
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
fab42f8
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
36d91ee
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
0ff2c78
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
7292bdc
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
9281331
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
bd769c9
fixup! feat(core): add Zcash shielded transactions
krnak Nov 18, 2022
204d76b
fix: make gen
krnak Nov 20, 2022
960b0db
fix(core): add `ZCASH_SHIELDED` flag to env
krnak Nov 20, 2022
0e8a7e4
fix(core): define `length` variable
krnak Nov 20, 2022
4cb1824
feat(python): modify zcash.sign_tx to use orchard_params
krnak Nov 20, 2022
c2a2fd1
style: make style
krnak Nov 20, 2022
a729459
fix(python): fix typing
krnak Nov 20, 2022
62001e3
feat(core): re-enable `RDI` and `SECP256K1_ZKP` flags
krnak Nov 20, 2022
83ab01b
fix(core): fix Zcash Orchard generators
krnak Nov 20, 2022
327a784
fix(python): fix zcash.sign_tx logging
krnak Nov 20, 2022
2931db9
doc(core): add a comment
krnak Nov 21, 2022
e5d373a
doc(core): add a comment to check_orchard_inputs_count
krnak Nov 21, 2022
a9c0820
fixup! feat(core): add Zcash shielded transactions
krnak Dec 16, 2022
f85e6a9
fix(core): add ZCASH_SHIELDED to CCPDEFINES_MOD
krnak Dec 16, 2022
4e8dcff
feat(core): show Zcash non-standard paths via address_extra
krnak Dec 17, 2022
9db9d3a
style: make style, fix a typo
krnak Dec 17, 2022
99b3804
fixup! feat(core): add Zcash shielded transactions
krnak Dec 17, 2022
7a67e9a
fixup! feat(core): add Zcash shielded transactions
krnak Dec 17, 2022
92560d0
fixup! feat(core): add Zcash shielded transactions
krnak Dec 17, 2022
107f8cd
fixup! fixup! feat(core): add Zcash shielded transactions
krnak Dec 17, 2022
7c7868f
fix(core): fix auto import
krnak Dec 20, 2022
7226cf9
fix(python): fix zcash typing
krnak Dec 20, 2022
e89c43b
test: add Zcash `get_address` and `get_viewing_key` device tests
krnak Dec 20, 2022
2728438
fix(core): change Zcash confirm-dust-inputs button to Warning
krnak Dec 27, 2022
40cfba5
fix(core): halt on too-long-memo already during outputs confirmation …
krnak Dec 27, 2022
6a01827
fix(python): fix typing by using Union type
krnak Dec 27, 2022
d562254
test(device_tests): remake Zcash sign shielded tx tests
krnak Dec 27, 2022
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
12 changes: 11 additions & 1 deletion common/protob/messages-bitcoin.proto
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ option (include_in_bitcoin_only) = true;

import "messages.proto";
import "messages-common.proto";
import "messages-zcash.proto";

/**
* Type of script which will be used for transaction input
Expand Down Expand Up @@ -197,6 +198,7 @@ message SignTx {
optional uint32 branch_id = 10; // only for Zcash, BRANCH_ID
optional AmountUnit amount_unit = 11 [default=BITCOIN]; // show amounts in
optional bool decred_staking_ticket = 12 [default=false]; // only for Decred, this is signing a ticket purchase
optional zcash.ZcashOrchardParams orchard_params = 13; // only for Zcash
}

/**
Expand All @@ -211,6 +213,8 @@ message SignTx {
* @next TxAckPrevOutput
* @next TxAckPrevExtraData
* @next TxAckPaymentRequest
* @next ZcashOrchardInput
* @next ZcashOrchardOutput
*/
message TxRequest {
optional RequestType request_type = 1; // what should be filled in TxAck message?
Expand All @@ -228,6 +232,9 @@ message TxRequest {
TXORIGINPUT = 5;
TXORIGOUTPUT = 6;
TXPAYMENTREQ = 7;
TXORCHARDOUTPUT = 8;
TXORCHARDINPUT = 9;
NO_OP = 10;
}
/**
* Structure representing request details
Expand All @@ -245,6 +252,10 @@ message TxRequest {
optional uint32 signature_index = 1; // 'signature' field contains signed input of this index
optional bytes signature = 2; // signature of the signature_index input
optional bytes serialized_tx = 3; // part of serialized and signed transaction

optional zcash.ZcashSignatureType signature_type = 4; // for Zcash only
optional bytes zcash_shielding_seed = 5; // for Zcash only
optional bytes tx_sighash = 6; // for Zcash only
}
}

Expand Down Expand Up @@ -607,4 +618,3 @@ message AuthorizeCoinJoin {
optional InputScriptType script_type = 7 [default=SPENDADDRESS]; // used to distinguish between various address formats (non-segwit, segwit, etc.)
optional AmountUnit amount_unit = 8 [default=BITCOIN]; // show amounts in
}

100 changes: 100 additions & 0 deletions common/protob/messages-zcash.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
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";

import "messages.proto";

enum ZcashSignatureType {
reserved 1, 2, 4;
TRANSPARENT = 0;
// SAPLING_SPEND_AUTH = 1;
// SAPLING_BINDING = 2;
ORCHARD_SPEND_AUTH = 3;
// ORCHARD_BINDING = 4;
}

/**
* Request: Ask device for Orchard Viewing Key.
* If field `full` is true, then Full Viewing Key will be returned.
* Otherwise Incoming Viewing Key will be returned.
*
* @start
* @next Failure
* @next ZcashViewingKey
*/
message ZcashGetViewingKey {
optional string coin_name = 1 [default = "Zcash"];
repeated uint32 z_address_n = 2; // z-address ZIP 32 path
optional bool full = 3 [default = true]; // true -> Full Viewing Key requested
// false -> Incoming Viewing Key requested
}

/**
* Response: Contains unified Full/Incoming Viewing Key.
* @end
*/
message ZcashViewingKey {
required string key = 1;
}

/**
* Request: Ask device for a Unified Address.
* @start
* @next Failure
* @next ZcashAddress
*/
message ZcashGetAddress {
optional string coin_name = 1 [default = "Zcash"];
repeated uint32 t_address_n = 2; // t-address BIP 32 path (P2PKH)
repeated uint32 z_address_n = 3; // z-address ZIP 32 path (Orchard)
optional uint64 diversifier_index = 4 [default = 0]; // z-address diversifier index
optional bool show_display = 5 [default = false]; // Optionally show on display before sending the result
}

/**
* Response: Contains Zcash diversified payment address derived from device private seed
* @end
*/
message ZcashAddress {
optional string address = 1;
}

/**
* Orchard signing params
* @embed
*/
message ZcashOrchardParams {
required uint32 inputs_count = 1;
required uint32 outputs_count = 2;
required bytes anchor = 3;
repeated uint32 address_n = 4;
}

/**
* Request: Specify transaction Orchard input.
* @next TxRequest
*/
message ZcashOrchardInput {
required bytes recipient = 1;
required uint64 value = 2;
required bytes rho = 3;
required bytes rseed = 4;
}

/**
* Request: Specify transaction Orchard output.
* Let the `address` and `memo` fields empty for change outputs.
* @next TxRequest
*/
message ZcashOrchardOutput {
optional string address = 1; // for outgoing transfers
required uint64 amount = 2;
optional string memo = 3; // an optional message for a recepient
}

message ZcashAck {
option (wire_type) = 22;
}
8 changes: 8 additions & 0 deletions common/protob/messages.proto
Original file line number Diff line number Diff line change
Expand Up @@ -357,4 +357,12 @@ enum MessageType {
MessageType_WebAuthnCredentials = 801 [(wire_out) = true];
MessageType_WebAuthnAddResidentCredential = 802 [(wire_in) = true];
MessageType_WebAuthnRemoveResidentCredential = 803 [(wire_in) = true];

// Zcash
MessageType_ZcashOrchardInput = 900 [(wire_in) = true];
MessageType_ZcashOrchardOutput = 901 [(wire_in) = true];
MessageType_ZcashGetAddress = 902 [(wire_in) = true];
MessageType_ZcashAddress = 903 [(wire_out) = true];
MessageType_ZcashGetViewingKey = 904 [(wire_in) = true];
MessageType_ZcashViewingKey = 905 [(wire_out) = true];
}
1 change: 1 addition & 0 deletions core/.changelog.d/2472.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add Zcash shielded transactions
15 changes: 13 additions & 2 deletions core/SConscript.firmware
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,12 @@ 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/zcash/*.py',
exclude=[
SOURCE_PY_DIR + 'apps/zcash/get_address.py',
SOURCE_PY_DIR + 'apps/zcash/get_viewing_key.py',
])
)

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

Expand All @@ -683,7 +688,13 @@ 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, zcash_shielded=FEATURE_FLAGS['ZCASH_SHIELDED'])
if FEATURE_FLAGS["ZCASH_SHIELDED"]:
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/zcash/orchard/*.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/zcash/orchard/*/*.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/zcash/get_address.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/zcash/get_viewing_key.py'))

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)
Expand Down
15 changes: 13 additions & 2 deletions core/SConscript.unix
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,12 @@ 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/zcash/*.py',
exclude=[
SOURCE_PY_DIR + 'apps/zcash/get_address.py',
SOURCE_PY_DIR + 'apps/zcash/get_viewing_key.py',
])
)

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

Expand All @@ -639,7 +644,13 @@ 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, zcash_shielded=FEATURE_FLAGS['ZCASH_SHIELDED'])
if FEATURE_FLAGS["ZCASH_SHIELDED"]:
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/zcash/orchard/*.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/zcash/orchard/*/*.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/zcash/get_address.py'))
SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'apps/zcash/get_viewing_key.py'))

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)
Expand Down
4 changes: 2 additions & 2 deletions core/embed/rust/Cargo.lock

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

5 changes: 3 additions & 2 deletions core/embed/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ default_features = false

[dependencies.pasta_curves]
optional = true
version = "0.4.0"
version = "0.4.1"
default-features = false
features = ["uninline-portable"]

# Build dependencies

Expand All @@ -88,4 +89,4 @@ path = "./blake2b_hal"

[patch.crates-io.pasta_curves]
git = "https://github.com/jarys/pasta_curves"
rev = "a4f755013aad344982383c9f5af362697d928325"
rev = "e11dfe4089d0da24483094a99cceb89f32974c17"
2 changes: 1 addition & 1 deletion core/embed/rust/librust_qstr.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ static void _librust_qstrs(void) {
MP_QSTR_to_scalar;
MP_QSTR_group_hash;
MP_QSTR_scalar_from_i64;
MP_QSTR_generators;
MP_QSTR_Generators;
MP_QSTR_SPENDING_KEY_BASE;
MP_QSTR_NULLIFIER_K_BASE;
MP_QSTR_VALUE_COMMITMENT_VALUE_BASE;
Expand Down
40 changes: 38 additions & 2 deletions core/embed/rust/src/zcash_primitives/pallas/generators.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,56 @@
//! Precomputed Orchard generators.
//!
//! There does not exist any static constructor for `pasta_curves::pallas::Point`,
//! hence generators cannot be direct module attributes.
//! Instead we allocate a `Generators()` object with overridden `attr_fn`.
//! This `attr_fn` maps generators qstr-names to the concrete points.
//!
//! Usage in python:
//! ```
//! gen = pallas.Generators()
//! ak = sk * gen.SPENDING_KEY_BASE
//! hasher = Sinsemilla(gen.IVK_COMMITMENT_Q)
//! ```

use crate::{
error::Error,
micropython::{ffi, obj::Obj, qstr::Qstr, typ::Type, util, wrap::Wrappable},
micropython::{ffi, map::Map, obj::Obj, qstr::Qstr, typ::Type, util, wrap::Wrappable},
};
use pasta_curves::{
arithmetic::CurveAffine,
pallas::{Affine, Point},
Fp,
};

struct Generators;

pub static GENERATORS_TYPE: Type = obj_type! {
name: Qstr::MP_QSTR_generators,
name: Qstr::MP_QSTR_Generators,
attr_fn: attr_fn,
make_new_fn: make_gens,
};

impl Wrappable for Generators {
fn obj_type() -> &'static Type {
&GENERATORS_TYPE
}
}

unsafe extern "C" fn make_gens(
_type_: *const Type,
n_args: usize,
n_kw: usize,
args: *const Obj,
) -> Obj {
let block = |args: &[Obj], kwargs: &Map| {
if args.len() != 0 || kwargs.len() != 0 {
return Err(Error::TypeError);
}
Generators.wrap()
};
unsafe { util::try_with_args_and_kwargs_inline(n_args, n_kw, args, block) }
}

unsafe extern "C" fn attr_fn(_self_in: Obj, attr: ffi::qstr, dest: *mut Obj) {
let block = || {
let attr = Qstr::from_u16(attr as _);
Expand Down
13 changes: 5 additions & 8 deletions core/embed/rust/src/zcash_primitives/pallas/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,14 @@ mod scalar;
#[no_mangle]
pub static mp_module_trezorpallas: Module = obj_module! {
Qstr::MP_QSTR___name__ => Qstr::MP_QSTR_trezorpallas.to_obj(),
/// # https://zips.z.cash/protocol/protocol.pdf#orchardkeycomponents
/// def to_base(x: bytes) -> Fp:
/// ...
/// """https://zips.z.cash/protocol/protocol.pdf#orchardkeycomponents"""
Qstr::MP_QSTR_to_base => obj_fn_1!(fp::to_base).as_obj(),
/// # https://zips.z.cash/protocol/protocol.pdf#orchardkeycomponents
/// def to_scalar(x: bytes) -> Scalar:
/// ...
/// """https://zips.z.cash/protocol/protocol.pdf#orchardkeycomponents"""
Qstr::MP_QSTR_to_scalar => obj_fn_1!(scalar::to_scalar).as_obj(),
/// # https://zips.z.cash/protocol/protocol.pdf#concretegrouphashpallasandvesta
/// def group_hash(domain: str, message: bytes) -> Point:
/// ...
/// """https://zips.z.cash/protocol/protocol.pdf#concretegrouphashpallasandvesta"""
Qstr::MP_QSTR_group_hash => obj_fn_2!(point::group_hash).as_obj(),
/// def scalar_from_i64(x: int) -> Scalar:
/// """Converts integer to Scalar."""
Expand Down Expand Up @@ -75,7 +72,7 @@ pub static mp_module_trezorpallas: Module = obj_module! {
/// def __neg__(self) -> Point:
/// ...
Qstr::MP_QSTR_Point => (&point::POINT_TYPE).as_obj(),
/// class generators:
/// class Generators:
/// SPENDING_KEY_BASE: Point
/// NULLIFIER_K_BASE: Point
/// VALUE_COMMITMENT_VALUE_BASE: Point
Expand All @@ -84,5 +81,5 @@ pub static mp_module_trezorpallas: Module = obj_module! {
/// NOTE_COMMITMENT_Q: Point
/// IVK_COMMITMENT_BASE: Point
/// IVK_COMMITMENT_Q: Point
Qstr::MP_QSTR_generators => (&generators::GENERATORS_TYPE).as_obj(),
Qstr::MP_QSTR_Generators => (&generators::GENERATORS_TYPE).as_obj(),
};
13 changes: 10 additions & 3 deletions core/embed/rust/src/zcash_primitives/pallas/scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,16 @@ unsafe extern "C" fn scalar_binary_op(op: ffi::mp_binary_op_t, this: Obj, other:
let this = this.deref().inner();
match op {
ffi::mp_binary_op_t_MP_BINARY_OP_MULTIPLY => {
let other = Gc::<Wrapped<Point>>::try_from(other)?;
let other = other.deref().inner();
(other * this).wrap()
let point = Gc::<Wrapped<Point>>::try_from(other);
if point.is_ok() {
let point = point.unwrap();
let point = point.deref().inner();
(point * this).wrap()
} else {
let scalar = Gc::<Wrapped<Scalar>>::try_from(other)?;
let scalar = scalar.deref().inner();
(this * scalar).wrap()
}
}
ffi::mp_binary_op_t_MP_BINARY_OP_ADD => {
let other = Gc::<Wrapped<Scalar>>::try_from(other)?;
Expand Down
Loading