1
0
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:
Tomas Krnak 2022-11-17 12:42:41 +07:00
parent ac73bfaf1e
commit dc2057d10e
7 changed files with 25 additions and 61 deletions

View File

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

View File

@ -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"
)

View File

@ -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()

View File

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

View File

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

View File

@ -11,4 +11,5 @@ if utils.ZCASH_SHIELDED:
scalar_from_i64,
to_base,
to_scalar,
generators,
)

View File

@ -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")