Compare commits
No commits in common. "main" and "0.2.0" have entirely different histories.
|
@ -1,10 +0,0 @@
|
||||||
version: 2
|
|
||||||
updates:
|
|
||||||
- package-ecosystem: github-actions
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: daily
|
|
||||||
timezone: Etc/UTC
|
|
||||||
open-pull-requests-limit: 10
|
|
||||||
labels:
|
|
||||||
- "A-CI"
|
|
|
@ -1,88 +0,0 @@
|
||||||
name: CI checks
|
|
||||||
|
|
||||||
on: [push, pull_request]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
name: Test on ${{ matrix.os }}
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Run tests
|
|
||||||
run: cargo test --all-features --verbose
|
|
||||||
- name: Verify working directory is clean
|
|
||||||
run: git diff --exit-code
|
|
||||||
|
|
||||||
build-latest:
|
|
||||||
name: Latest build on ${{ matrix.os }}
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
|
||||||
id: toolchain
|
|
||||||
- run: rustup override set ${{steps.toolchain.outputs.name}}
|
|
||||||
- name: Remove lockfile to build with latest dependencies
|
|
||||||
run: rm Cargo.lock
|
|
||||||
- name: Build crate
|
|
||||||
run: cargo build --all-targets --all-features --verbose
|
|
||||||
- name: Verify working directory is clean (excluding lockfile)
|
|
||||||
run: git diff --exit-code ':!Cargo.lock'
|
|
||||||
|
|
||||||
build-nodefault:
|
|
||||||
name: Build target ${{ matrix.target }}
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
target:
|
|
||||||
- wasm32-wasi
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Add target
|
|
||||||
run: rustup target add ${{ matrix.target }}
|
|
||||||
- name: Build crate
|
|
||||||
run: cargo build --no-default-features --verbose --target ${{ matrix.target }}
|
|
||||||
|
|
||||||
bitrot:
|
|
||||||
name: Bitrot check
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
# Build benchmarks to prevent bitrot
|
|
||||||
- name: Build benchmarks
|
|
||||||
run: cargo build --benches
|
|
||||||
|
|
||||||
clippy:
|
|
||||||
name: Clippy (MSRV)
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Run Clippy
|
|
||||||
uses: auguwu/clippy-action@1.3.0
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
working-directory: ${{ inputs.target }}
|
|
||||||
deny: warnings
|
|
||||||
|
|
||||||
doc-links:
|
|
||||||
name: Intra-doc links
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- run: cargo fetch
|
|
||||||
# Requires #![deny(rustdoc::broken_intra_doc_links)] in crate.
|
|
||||||
- name: Check intra-doc links
|
|
||||||
run: cargo doc --all-features --document-private-items
|
|
||||||
|
|
||||||
fmt:
|
|
||||||
name: Rustfmt
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Check formatting
|
|
||||||
run: cargo fmt -- --check
|
|
|
@ -1 +0,0 @@
|
||||||
target
|
|
19
CHANGELOG.md
19
CHANGELOG.md
|
@ -7,25 +7,6 @@ and this library adheres to Rust's notion of
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
## [0.4.0] - 2023-06-06
|
|
||||||
### Changed
|
|
||||||
- The `esk` and `ephemeral_key` arguments have been removed from
|
|
||||||
`Domain::parse_note_plaintext_without_memo_ovk`. It is therefore no longer
|
|
||||||
necessary (or possible) to ensure that `ephemeral_key` is derived from `esk`
|
|
||||||
and the diversifier within the note plaintext. We have analyzed the safety of
|
|
||||||
this change in the context of callers within `zcash_note_encryption` and
|
|
||||||
`orchard`. See https://github.com/zcash/librustzcash/pull/848 and the
|
|
||||||
associated issue https://github.com/zcash/librustzcash/issues/802 for
|
|
||||||
additional detail.
|
|
||||||
|
|
||||||
## [0.3.0] - 2023-03-22
|
|
||||||
### Changed
|
|
||||||
- The `recipient` parameter has been removed from `Domain::note_plaintext_bytes`.
|
|
||||||
- The `recipient` parameter has been removed from `NoteEncryption::new`. Since
|
|
||||||
the `Domain::Note` type is now expected to contain information about the
|
|
||||||
recipient of the note, there is no longer any need to pass this information
|
|
||||||
in via the encryption context.
|
|
||||||
|
|
||||||
## [0.2.0] - 2022-10-13
|
## [0.2.0] - 2022-10-13
|
||||||
### Added
|
### Added
|
||||||
- `zcash_note_encryption::Domain`:
|
- `zcash_note_encryption::Domain`:
|
||||||
|
|
|
@ -1,166 +0,0 @@
|
||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "aead"
|
|
||||||
version = "0.5.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
|
|
||||||
dependencies = [
|
|
||||||
"crypto-common",
|
|
||||||
"generic-array",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg-if"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "chacha20"
|
|
||||||
version = "0.9.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"cipher",
|
|
||||||
"cpufeatures",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "chacha20poly1305"
|
|
||||||
version = "0.10.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35"
|
|
||||||
dependencies = [
|
|
||||||
"aead",
|
|
||||||
"chacha20",
|
|
||||||
"cipher",
|
|
||||||
"poly1305",
|
|
||||||
"zeroize",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cipher"
|
|
||||||
version = "0.4.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
|
|
||||||
dependencies = [
|
|
||||||
"crypto-common",
|
|
||||||
"inout",
|
|
||||||
"zeroize",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cpufeatures"
|
|
||||||
version = "0.2.11"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "crypto-common"
|
|
||||||
version = "0.1.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
|
||||||
dependencies = [
|
|
||||||
"generic-array",
|
|
||||||
"typenum",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "generic-array"
|
|
||||||
version = "0.14.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
|
||||||
dependencies = [
|
|
||||||
"typenum",
|
|
||||||
"version_check",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "inout"
|
|
||||||
version = "0.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
|
|
||||||
dependencies = [
|
|
||||||
"generic-array",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libc"
|
|
||||||
version = "0.2.150"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "opaque-debug"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "poly1305"
|
|
||||||
version = "0.8.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf"
|
|
||||||
dependencies = [
|
|
||||||
"cpufeatures",
|
|
||||||
"opaque-debug",
|
|
||||||
"universal-hash",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_core"
|
|
||||||
version = "0.6.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "subtle"
|
|
||||||
version = "2.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "typenum"
|
|
||||||
version = "1.17.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "universal-hash"
|
|
||||||
version = "0.5.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
|
|
||||||
dependencies = [
|
|
||||||
"crypto-common",
|
|
||||||
"subtle",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "version_check"
|
|
||||||
version = "0.9.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zcash_note_encryption"
|
|
||||||
version = "0.4.0"
|
|
||||||
dependencies = [
|
|
||||||
"chacha20",
|
|
||||||
"chacha20poly1305",
|
|
||||||
"cipher",
|
|
||||||
"rand_core",
|
|
||||||
"subtle",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "zeroize"
|
|
||||||
version = "1.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9"
|
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "zcash_note_encryption"
|
name = "zcash_note_encryption"
|
||||||
description = "Note encryption for Zcash transactions"
|
description = "Note encryption for Zcash transactions"
|
||||||
version = "0.4.0"
|
version = "0.2.0"
|
||||||
authors = [
|
authors = [
|
||||||
"Jack Grigg <jack@electriccoin.co>",
|
"Jack Grigg <jack@electriccoin.co>",
|
||||||
"Kris Nuttycombe <kris@electriccoin.co>"
|
"Kris Nuttycombe <kris@electriccoin.co>"
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
[toolchain]
|
|
||||||
channel = "1.56.1"
|
|
||||||
components = ["clippy", "rustfmt"]
|
|
65
src/lib.rs
65
src/lib.rs
|
@ -19,8 +19,6 @@
|
||||||
#![deny(unsafe_code)]
|
#![deny(unsafe_code)]
|
||||||
// TODO: #![deny(missing_docs)]
|
// TODO: #![deny(missing_docs)]
|
||||||
|
|
||||||
use core::fmt::{self, Write};
|
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
|
@ -74,28 +72,9 @@ impl AsRef<[u8]> for OutgoingCipherKey {
|
||||||
/// Newtype representing the byte encoding of an [`EphemeralPublicKey`].
|
/// Newtype representing the byte encoding of an [`EphemeralPublicKey`].
|
||||||
///
|
///
|
||||||
/// [`EphemeralPublicKey`]: Domain::EphemeralPublicKey
|
/// [`EphemeralPublicKey`]: Domain::EphemeralPublicKey
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct EphemeralKeyBytes(pub [u8; 32]);
|
pub struct EphemeralKeyBytes(pub [u8; 32]);
|
||||||
|
|
||||||
impl fmt::Debug for EphemeralKeyBytes {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
struct HexFmt<'b>(&'b [u8]);
|
|
||||||
impl<'b> fmt::Debug for HexFmt<'b> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
f.write_char('"')?;
|
|
||||||
for b in self.0 {
|
|
||||||
f.write_fmt(format_args!("{:02x}", b))?;
|
|
||||||
}
|
|
||||||
f.write_char('"')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
f.debug_tuple("EphemeralKeyBytes")
|
|
||||||
.field(&HexFmt(&self.0))
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsRef<[u8]> for EphemeralKeyBytes {
|
impl AsRef<[u8]> for EphemeralKeyBytes {
|
||||||
fn as_ref(&self) -> &[u8] {
|
fn as_ref(&self) -> &[u8] {
|
||||||
&self.0
|
&self.0
|
||||||
|
@ -192,7 +171,20 @@ pub trait Domain {
|
||||||
fn kdf(secret: Self::SharedSecret, ephemeral_key: &EphemeralKeyBytes) -> Self::SymmetricKey;
|
fn kdf(secret: Self::SharedSecret, ephemeral_key: &EphemeralKeyBytes) -> Self::SymmetricKey;
|
||||||
|
|
||||||
/// Encodes the given `Note` and `Memo` as a note plaintext.
|
/// Encodes the given `Note` and `Memo` as a note plaintext.
|
||||||
fn note_plaintext_bytes(note: &Self::Note, memo: &Self::Memo) -> NotePlaintextBytes;
|
///
|
||||||
|
/// # Future breaking changes
|
||||||
|
///
|
||||||
|
/// The `recipient` argument is present as a secondary way to obtain the diversifier;
|
||||||
|
/// this is due to a historical quirk of how the Sapling `Note` struct was implemented
|
||||||
|
/// in the `zcash_primitives` crate. `recipient` will be removed from this method in a
|
||||||
|
/// future crate release, once [`zcash_primitives` has been refactored].
|
||||||
|
///
|
||||||
|
/// [`zcash_primitives` has been refactored]: https://github.com/zcash/librustzcash/issues/454
|
||||||
|
fn note_plaintext_bytes(
|
||||||
|
note: &Self::Note,
|
||||||
|
recipient: &Self::Recipient,
|
||||||
|
memo: &Self::Memo,
|
||||||
|
) -> NotePlaintextBytes;
|
||||||
|
|
||||||
/// Derives the [`OutgoingCipherKey`] for an encrypted note, given the note-specific
|
/// Derives the [`OutgoingCipherKey`] for an encrypted note, given the note-specific
|
||||||
/// public data and an `OutgoingViewingKey`.
|
/// public data and an `OutgoingViewingKey`.
|
||||||
|
@ -250,6 +242,8 @@ pub trait Domain {
|
||||||
/// which may be passed via `self`).
|
/// which may be passed via `self`).
|
||||||
/// - The note plaintext contains valid encodings of its various fields.
|
/// - The note plaintext contains valid encodings of its various fields.
|
||||||
/// - Any domain-specific requirements are satisfied.
|
/// - Any domain-specific requirements are satisfied.
|
||||||
|
/// - `ephemeral_key` can be derived from `esk` and the diversifier within the note
|
||||||
|
/// plaintext.
|
||||||
///
|
///
|
||||||
/// `&self` is passed here to enable the implementation to enforce contextual checks,
|
/// `&self` is passed here to enable the implementation to enforce contextual checks,
|
||||||
/// such as rules like [ZIP 212] that become active at a specific block height.
|
/// such as rules like [ZIP 212] that become active at a specific block height.
|
||||||
|
@ -258,6 +252,8 @@ pub trait Domain {
|
||||||
fn parse_note_plaintext_without_memo_ovk(
|
fn parse_note_plaintext_without_memo_ovk(
|
||||||
&self,
|
&self,
|
||||||
pk_d: &Self::DiversifiedTransmissionKey,
|
pk_d: &Self::DiversifiedTransmissionKey,
|
||||||
|
esk: &Self::EphemeralSecretKey,
|
||||||
|
ephemeral_key: &EphemeralKeyBytes,
|
||||||
plaintext: &NotePlaintextBytes,
|
plaintext: &NotePlaintextBytes,
|
||||||
) -> Option<(Self::Note, Self::Recipient)>;
|
) -> Option<(Self::Note, Self::Recipient)>;
|
||||||
|
|
||||||
|
@ -353,6 +349,7 @@ pub struct NoteEncryption<D: Domain> {
|
||||||
epk: D::EphemeralPublicKey,
|
epk: D::EphemeralPublicKey,
|
||||||
esk: D::EphemeralSecretKey,
|
esk: D::EphemeralSecretKey,
|
||||||
note: D::Note,
|
note: D::Note,
|
||||||
|
to: D::Recipient,
|
||||||
memo: D::Memo,
|
memo: D::Memo,
|
||||||
/// `None` represents the `ovk = ⊥` case.
|
/// `None` represents the `ovk = ⊥` case.
|
||||||
ovk: Option<D::OutgoingViewingKey>,
|
ovk: Option<D::OutgoingViewingKey>,
|
||||||
|
@ -361,12 +358,18 @@ pub struct NoteEncryption<D: Domain> {
|
||||||
impl<D: Domain> NoteEncryption<D> {
|
impl<D: Domain> NoteEncryption<D> {
|
||||||
/// Construct a new note encryption context for the specified note,
|
/// Construct a new note encryption context for the specified note,
|
||||||
/// recipient, and memo.
|
/// recipient, and memo.
|
||||||
pub fn new(ovk: Option<D::OutgoingViewingKey>, note: D::Note, memo: D::Memo) -> Self {
|
pub fn new(
|
||||||
|
ovk: Option<D::OutgoingViewingKey>,
|
||||||
|
note: D::Note,
|
||||||
|
to: D::Recipient,
|
||||||
|
memo: D::Memo,
|
||||||
|
) -> Self {
|
||||||
let esk = D::derive_esk(¬e).expect("ZIP 212 is active.");
|
let esk = D::derive_esk(¬e).expect("ZIP 212 is active.");
|
||||||
NoteEncryption {
|
NoteEncryption {
|
||||||
epk: D::ka_derive_public(¬e, &esk),
|
epk: D::ka_derive_public(¬e, &esk),
|
||||||
esk,
|
esk,
|
||||||
note,
|
note,
|
||||||
|
to,
|
||||||
memo,
|
memo,
|
||||||
ovk,
|
ovk,
|
||||||
}
|
}
|
||||||
|
@ -381,12 +384,14 @@ impl<D: Domain> NoteEncryption<D> {
|
||||||
esk: D::EphemeralSecretKey,
|
esk: D::EphemeralSecretKey,
|
||||||
ovk: Option<D::OutgoingViewingKey>,
|
ovk: Option<D::OutgoingViewingKey>,
|
||||||
note: D::Note,
|
note: D::Note,
|
||||||
|
to: D::Recipient,
|
||||||
memo: D::Memo,
|
memo: D::Memo,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
NoteEncryption {
|
NoteEncryption {
|
||||||
epk: D::ka_derive_public(¬e, &esk),
|
epk: D::ka_derive_public(¬e, &esk),
|
||||||
esk,
|
esk,
|
||||||
note,
|
note,
|
||||||
|
to,
|
||||||
memo,
|
memo,
|
||||||
ovk,
|
ovk,
|
||||||
}
|
}
|
||||||
|
@ -407,7 +412,7 @@ impl<D: Domain> NoteEncryption<D> {
|
||||||
let pk_d = D::get_pk_d(&self.note);
|
let pk_d = D::get_pk_d(&self.note);
|
||||||
let shared_secret = D::ka_agree_enc(&self.esk, &pk_d);
|
let shared_secret = D::ka_agree_enc(&self.esk, &pk_d);
|
||||||
let key = D::kdf(shared_secret, &D::epk_bytes(&self.epk));
|
let key = D::kdf(shared_secret, &D::epk_bytes(&self.epk));
|
||||||
let input = D::note_plaintext_bytes(&self.note, &self.memo);
|
let input = D::note_plaintext_bytes(&self.note, &self.to, &self.memo);
|
||||||
|
|
||||||
let mut output = [0u8; ENC_CIPHERTEXT_SIZE];
|
let mut output = [0u8; ENC_CIPHERTEXT_SIZE];
|
||||||
output[..NOTE_PLAINTEXT_SIZE].copy_from_slice(&input.0);
|
output[..NOTE_PLAINTEXT_SIZE].copy_from_slice(&input.0);
|
||||||
|
@ -534,8 +539,6 @@ fn check_note_validity<D: Domain>(
|
||||||
cmstar_bytes: &D::ExtractedCommitmentBytes,
|
cmstar_bytes: &D::ExtractedCommitmentBytes,
|
||||||
) -> NoteValidity {
|
) -> NoteValidity {
|
||||||
if &D::ExtractedCommitmentBytes::from(&D::cmstar(note)) == cmstar_bytes {
|
if &D::ExtractedCommitmentBytes::from(&D::cmstar(note)) == cmstar_bytes {
|
||||||
// In the case corresponding to specification section 4.19.3, we check that `esk` is equal
|
|
||||||
// to `D::derive_esk(note)` prior to calling this method.
|
|
||||||
if let Some(derived_esk) = D::derive_esk(note) {
|
if let Some(derived_esk) = D::derive_esk(note) {
|
||||||
if D::epk_bytes(&D::ka_derive_public(note, &derived_esk))
|
if D::epk_bytes(&D::ka_derive_public(note, &derived_esk))
|
||||||
.ct_eq(ephemeral_key)
|
.ct_eq(ephemeral_key)
|
||||||
|
@ -674,12 +677,12 @@ pub fn try_output_recovery_with_ock<D: Domain, Output: ShieldedOutput<D, ENC_CIP
|
||||||
)
|
)
|
||||||
.ok()?;
|
.ok()?;
|
||||||
|
|
||||||
let (note, to) = domain.parse_note_plaintext_without_memo_ovk(&pk_d, &plaintext)?;
|
let (note, to) =
|
||||||
|
domain.parse_note_plaintext_without_memo_ovk(&pk_d, &esk, &ephemeral_key, &plaintext)?;
|
||||||
let memo = domain.extract_memo(&plaintext);
|
let memo = domain.extract_memo(&plaintext);
|
||||||
|
|
||||||
// ZIP 212: Check that the esk provided to this function is consistent with the esk we can
|
// ZIP 212: Check that the esk provided to this function is consistent with the esk we
|
||||||
// derive from the note. This check corresponds to `ToScalar(PRF^{expand}_{rseed}([4]) = esk`
|
// can derive from the note.
|
||||||
// in https://zips.z.cash/protocol/protocol.pdf#decryptovk. (`ρ^opt = []` for Sapling.)
|
|
||||||
if let Some(derived_esk) = D::derive_esk(¬e) {
|
if let Some(derived_esk) = D::derive_esk(¬e) {
|
||||||
if (!derived_esk.ct_eq(&esk)).into() {
|
if (!derived_esk.ct_eq(&esk)).into() {
|
||||||
return None;
|
return None;
|
||||||
|
|
Loading…
Reference in New Issue