mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-14 11:39:03 +00:00
refactor(core): move Zcash generators module to Rust
This commit is contained in:
parent
ac73bfaf1e
commit
dc2057d10e
@ -1,13 +1,8 @@
|
||||
import gc
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from trezor.crypto.pallas import Point, Scalar, scalar_from_i64
|
||||
from trezor.crypto.pallas import Point, Scalar, generators as gen, scalar_from_i64
|
||||
|
||||
from .generators import (
|
||||
SPENDING_KEY_BASE,
|
||||
VALUE_COMMITMENT_RANDOMNESS_BASE,
|
||||
VALUE_COMMITMENT_VALUE_BASE,
|
||||
)
|
||||
from .keys import FullViewingKey, sk_to_ask
|
||||
from .note import Note
|
||||
from .note_encryption import encrypt_note
|
||||
@ -19,8 +14,8 @@ if TYPE_CHECKING:
|
||||
|
||||
# https://zips.z.cash/protocol/nu5.pdf#concretehomomorphiccommit
|
||||
def commit_value(rcv: Scalar, v: int):
|
||||
V = scalar_from_i64(v) * VALUE_COMMITMENT_VALUE_BASE
|
||||
R = rcv * VALUE_COMMITMENT_RANDOMNESS_BASE
|
||||
V = scalar_from_i64(v) * gen.VALUE_COMMITMENT_VALUE_BASE
|
||||
R = rcv * gen.VALUE_COMMITMENT_RANDOMNESS_BASE
|
||||
return V + R
|
||||
|
||||
|
||||
@ -87,7 +82,7 @@ def build_action(
|
||||
# verification key
|
||||
alpha = rng.alpha()
|
||||
akP = Point(input.fvk.ak.to_bytes())
|
||||
rk = akP + alpha * SPENDING_KEY_BASE
|
||||
rk = akP + alpha * gen.SPENDING_KEY_BASE
|
||||
|
||||
# note commitment
|
||||
note = Note(
|
||||
|
@ -1,35 +0,0 @@
|
||||
"""Precomputed Orchard generators."""
|
||||
|
||||
from trezor.crypto.pallas import Point
|
||||
|
||||
# https://zips.z.cash/protocol/nu5.pdf#concretespendauthsig
|
||||
SPENDING_KEY_BASE = Point(
|
||||
b"\x63\xc9\x75\xb8\x84\x72\x1a\x8d\x0c\xa1\x70\x7b\xe3\x0c\x7f\x0c\x5f\x44\x5f\x3e\x7c\x18\x8d\x3b\x06\xd6\xf1\x28\xb3\x23\x55\xb7"
|
||||
)
|
||||
|
||||
# https://zips.z.cash/protocol/nu5.pdf#commitmentsandnullifiers
|
||||
NULLIFIER_K_BASE = Point(
|
||||
b"\x75\xca\x47\xe4\xa7\x6a\x6f\xd3\x9b\xdb\xb5\xcc\x92\xb1\x7e\x5e\xcf\xc9\xf4\xfa\x71\x55\x37\x2e\x8d\x19\xa8\x9c\x16\xaa\xe7\x25"
|
||||
)
|
||||
|
||||
# https://zips.z.cash/protocol/nu5.pdf#concretehomomorphiccommit
|
||||
VALUE_COMMITMENT_VALUE_BASE = Point(
|
||||
b"\x67\x43\xf9\x3a\x6e\xbd\xa7\x2a\x8c\x7c\x5a\x2b\x7f\xa3\x04\xfe\x32\xb2\x9b\x4f\x70\x6a\xa8\xf7\x42\x0f\x3d\x8e\x7a\x59\x70\x2f"
|
||||
)
|
||||
VALUE_COMMITMENT_RANDOMNESS_BASE = Point(
|
||||
b"\x91\x5a\x3c\x88\x68\xc6\xc3\x0e\x2f\x80\x90\xee\x45\xd7\x6e\x40\x48\x20\x8d\xea\x5b\x23\x66\x4f\xbb\x09\xa4\x0f\x55\x44\xf4\x07"
|
||||
)
|
||||
|
||||
# https://zips.z.cash/protocol/protocol.pdf#concretesinsemillacommit
|
||||
NOTE_COMMITMENT_BASE = Point(
|
||||
b"\x13\x6e\xfc\x0f\x48\x2c\x02\x2c\x7c\xa4\x14\xfc\x5c\xc5\x9e\x23\xf2\x3d\x6f\x93\xab\x9f\x23\xcd\x33\x45\xa9\x28\xc3\x06\xb2\xa6"
|
||||
)
|
||||
NOTE_COMMITMENT_Q = Point(
|
||||
b"\x5d\x74\xa8\x40\x09\xba\x0e\x32\x2a\xdd\x46\xfd\x5a\x0f\x96\xc5\x5d\xed\xb0\x79\xb4\xf2\x9f\xf7\x0d\xcd\xfb\x56\xa0\x07\x80\x97"
|
||||
)
|
||||
IVK_COMMITMENT_BASE = Point(
|
||||
b"\x18\xa1\xf8\x5f\x6e\x48\x23\x98\xc7\xed\x1a\xd3\xe2\x7f\x95\x02\x48\x89\x80\x40\x0a\x29\x34\x16\x4e\x13\x70\x50\xcd\x2c\xa2\xa5"
|
||||
)
|
||||
IVK_COMMITMENT_Q = Point(
|
||||
b"\xf2\x82\x0f\x79\x92\x2f\xcb\x6b\x32\xa2\x28\x51\x24\xcc\x1b\x42\xfa\x41\xa2\x5a\xb8\x81\xcc\x7d\x11\xc8\xa9\x4a\xf1\x0c\xbc\x05"
|
||||
)
|
@ -1,11 +1,10 @@
|
||||
# https://zips.z.cash/protocol/protocol.pdf#orchardkeycomponents
|
||||
|
||||
from trezor.crypto.pallas import Fp, Scalar, to_base, to_scalar
|
||||
from trezor.crypto.pallas import Fp, Scalar, generators as gen, to_base, to_scalar
|
||||
from trezor.utils import ensure
|
||||
|
||||
from . import ff1
|
||||
from .address import Address
|
||||
from .generators import IVK_COMMITMENT_BASE, IVK_COMMITMENT_Q, SPENDING_KEY_BASE
|
||||
from .sinsemilla import Sinsemilla
|
||||
from .utils import i2lebsp, prf_expand
|
||||
|
||||
@ -13,7 +12,7 @@ from .utils import i2lebsp, prf_expand
|
||||
def sk_to_ask(sk: bytes) -> Scalar:
|
||||
"""Derives Spend Authorizing Key from Spending Key."""
|
||||
ask = to_scalar(prf_expand(sk, b"\x06"))
|
||||
akP = ask * SPENDING_KEY_BASE
|
||||
akP = ask * gen.SPENDING_KEY_BASE
|
||||
if akP.to_bytes()[-1] & 0x80 != 0:
|
||||
ask = -ask
|
||||
ensure(ask) # ask != 0
|
||||
@ -57,7 +56,7 @@ class FullViewingKey:
|
||||
nk = to_base(prf_expand(sk, b"\x07"))
|
||||
rivk = to_scalar(prf_expand(sk, b"\x08"))
|
||||
ensure(ask) # ask != 0
|
||||
ak = (ask * SPENDING_KEY_BASE).extract()
|
||||
ak = (ask * gen.SPENDING_KEY_BASE).extract()
|
||||
return FullViewingKey(ak, nk, rivk)
|
||||
|
||||
# https://zips.z.cash/protocol/protocol.pdf#orchardfullviewingkeyencoding
|
||||
@ -107,8 +106,8 @@ class FullViewingKey:
|
||||
|
||||
# https://zips.z.cash/protocol/nu5.pdf#concreteNotecommit
|
||||
def commit_ivk(rivk: Scalar, ak: Fp, nk: Fp) -> Fp:
|
||||
h = Sinsemilla(IVK_COMMITMENT_Q)
|
||||
h = Sinsemilla(gen.IVK_COMMITMENT_Q)
|
||||
h.update(i2lebsp(255, ak))
|
||||
h.update(i2lebsp(255, nk))
|
||||
commitment = h.finalize() + rivk * IVK_COMMITMENT_BASE
|
||||
commitment = h.finalize() + rivk * gen.IVK_COMMITMENT_BASE
|
||||
return commitment.extract()
|
||||
|
@ -1,7 +1,14 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from trezor.crypto.hashlib import poseidon
|
||||
from trezor.crypto.pallas import Fp, Point, Scalar, to_base, to_scalar
|
||||
from trezor.crypto.pallas import (
|
||||
Fp,
|
||||
Point,
|
||||
Scalar,
|
||||
generators as gen,
|
||||
to_base,
|
||||
to_scalar,
|
||||
)
|
||||
from trezor.messages import ZcashOrchardInput
|
||||
|
||||
from apps.common.writers import (
|
||||
@ -12,7 +19,6 @@ from apps.common.writers import (
|
||||
)
|
||||
|
||||
from .address import Address
|
||||
from .generators import NOTE_COMMITMENT_BASE, NOTE_COMMITMENT_Q, NULLIFIER_K_BASE
|
||||
from .sinsemilla import Sinsemilla
|
||||
from .utils import i2lebsp, leos2bsp, prf_expand
|
||||
|
||||
@ -52,19 +58,19 @@ class Note:
|
||||
|
||||
# https://zips.z.cash/protocol/nu5.pdf#concreteNotecommit
|
||||
def commitment(self) -> Point:
|
||||
h = Sinsemilla(NOTE_COMMITMENT_Q)
|
||||
h = Sinsemilla(gen.NOTE_COMMITMENT_Q)
|
||||
h.update(leos2bsp(self.recipient.g_d().to_bytes()))
|
||||
h.update(leos2bsp(self.recipient.pk_d.to_bytes()))
|
||||
h.update(i2lebsp(64, self.value))
|
||||
h.update(i2lebsp(255, self.rho))
|
||||
h.update(i2lebsp(255, self.psi()))
|
||||
return h.finalize() + self.rcm() * NOTE_COMMITMENT_BASE
|
||||
return h.finalize() + self.rcm() * gen.NOTE_COMMITMENT_BASE
|
||||
|
||||
# https://zips.z.cash/protocol/protocol.pdf#commitmentsandnullifiers
|
||||
def nullifier(self, nk: Fp) -> Fp:
|
||||
base = poseidon(nk, self.rho) + self.psi()
|
||||
scalar = Scalar(base.to_bytes())
|
||||
point = scalar * NULLIFIER_K_BASE + self.commitment()
|
||||
point = scalar * gen.NULLIFIER_K_BASE + self.commitment()
|
||||
return point.extract()
|
||||
|
||||
# https://zips.z.cash/protocol/nu5.pdf#notept
|
||||
|
@ -3,9 +3,8 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from trezor.crypto.hashlib import blake2b
|
||||
from trezor.crypto.pallas import to_scalar
|
||||
from trezor.crypto.pallas import generators as gen, to_scalar
|
||||
|
||||
from .generators import SPENDING_KEY_BASE
|
||||
from .utils import xor
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -32,9 +31,9 @@ def sign_spend_auth(sk: Scalar, message: bytes, rng: ActionShieldingRng) -> byte
|
||||
# - `rng.spend_auth_T()` randomizes the signature
|
||||
# - xoring with bytes of `sk` makes `T` unpredictable for outside
|
||||
|
||||
vk: bytes = (sk * SPENDING_KEY_BASE).to_bytes()
|
||||
vk: bytes = (sk * gen.SPENDING_KEY_BASE).to_bytes()
|
||||
r: Scalar = H_star(T + vk + message)
|
||||
R: bytes = (r * SPENDING_KEY_BASE).to_bytes()
|
||||
R: bytes = (r * gen.SPENDING_KEY_BASE).to_bytes()
|
||||
e: Scalar = H_star(R + vk + message)
|
||||
S: bytes = (r + e * sk).to_bytes()
|
||||
return R + S
|
||||
|
@ -11,4 +11,5 @@ if utils.ZCASH_SHIELDED:
|
||||
scalar_from_i64,
|
||||
to_base,
|
||||
to_scalar,
|
||||
generators,
|
||||
)
|
||||
|
@ -1,6 +1,5 @@
|
||||
from common import *
|
||||
from trezor.crypto.pallas import group_hash, Point
|
||||
from apps.zcash.orchard.crypto import generators as gen
|
||||
from trezor.crypto.pallas import group_hash, Point, generators as gen
|
||||
|
||||
|
||||
@unittest.skipUnless(not utils.BITCOIN_ONLY, "altcoin")
|
||||
|
Loading…
Reference in New Issue
Block a user