Update master

This commit is contained in:
Aditya Kulkarni
2020-05-16 21:44:34 -07:00
218 changed files with 28917 additions and 19673 deletions

View File

@@ -1,20 +1,25 @@
[package]
name = "zcash_client_backend"
version = "0.0.0"
description = "APIs for creating shielded Zcash light clients"
version = "0.2.0"
authors = [
"Jack Grigg <jack@z.cash>",
]
homepage = "https://github.com/zcash/librustzcash"
repository = "https://github.com/zcash/librustzcash"
readme = "README.md"
license = "MIT OR Apache-2.0"
edition = "2018"
[dependencies]
bech32 = "0.7"
bs58 = { version = "0.2", features = ["check"] }
ff = { path = "../ff" }
ff = { version = "0.6", path = "../ff" }
hex = "0.3"
pairing = { path = "../pairing" }
pairing = { version = "0.16", path = "../pairing" }
protobuf = "2"
subtle = "2"
zcash_primitives = { path = "../zcash_primitives" }
zcash_primitives = { version = "0.2", path = "../zcash_primitives" }
[build-dependencies]
protobuf-codegen-pure = "2"
@@ -23,3 +28,6 @@ protobuf-codegen-pure = "2"
rand_core = "0.5"
rand_os = "0.2"
rand_xorshift = "0.2"
[badges]
maintenance = { status = "actively-developed" }

View File

@@ -1,12 +1,14 @@
# zcash_client_backend
This library contains Rust structs and traits for creating shielded Zcash light clients.
This library contains Rust structs and traits for creating shielded Zcash light
clients.
## License
Licensed under either of
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.

View File

@@ -1,8 +1,8 @@
//! Zcash global and per-network constants.
pub mod mainnet;
pub mod testnet;
pub mod regtest;
pub mod testnet;
pub const SPROUT_CONSENSUS_BRANCH_ID: u32 = 0;
pub const OVERWINTER_CONSENSUS_BRANCH_ID: u32 = 0x5ba8_1b19;

View File

@@ -1,3 +1,5 @@
//! Constants for the Zcash main network.
/// The mainnet coin type for ZEC, as defined by [SLIP 44].
///
/// [SLIP 44]: https://github.com/satoshilabs/slips/blob/master/slip-0044.md
@@ -23,7 +25,7 @@ pub const HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY: &str = "zxviews";
///
/// Defined in section 5.6.4 of the [Zcash Protocol Specification].
///
/// [`PaymentAddress`]: sapling_crypto::primitives::PaymentAddress
/// [`PaymentAddress`]: zcash_primitives::primitives::PaymentAddress
/// [Zcash Protocol Specification]: https://github.com/zcash/zips/blob/master/protocol/protocol.pdf
pub const HRP_SAPLING_PAYMENT_ADDRESS: &str = "zs";

View File

@@ -1,38 +1,45 @@
/// The testnet coin type for ZEC, as defined by [SLIP 44].
///
/// [SLIP 44]: https://github.com/satoshilabs/slips/blob/master/slip-0044.md
//! # Regtest constants
//!
//! `regtest` is a `zcashd`-specific environment used for local testing. They mostly reuse
//! the testnet constants.
//! These constants are defined in [the `zcashd` codebase].
//! [the `zcashd` codebase]: https://github.com/zcash/zcash/blob/128d863fb8be39ee294fda397c1ce3ba3b889cb2/src/chainparams.cpp#L482-L496
/// The regtest cointype reuses the testnet cointype
pub const COIN_TYPE: u32 = 1;
/// The HRP for a Bech32-encoded testnet [`ExtendedSpendingKey`].
/// The HRP for a Bech32-encoded regtest [`ExtendedSpendingKey`].
///
/// Defined in [ZIP 32].
/// It is defined in [the `zcashd` codebase].
///
/// [`ExtendedSpendingKey`]: zcash_primitives::zip32::ExtendedSpendingKey
/// [ZIP 32]: https://github.com/zcash/zips/blob/master/zip-0032.rst
/// [the `zcashd` codebase]: https://github.com/zcash/zcash/blob/128d863fb8be39ee294fda397c1ce3ba3b889cb2/src/chainparams.cpp#L496
pub const HRP_SAPLING_EXTENDED_SPENDING_KEY: &str = "secret-extended-key-regtest";
/// The HRP for a Bech32-encoded testnet [`ExtendedFullViewingKey`].
/// The HRP for a Bech32-encoded regtest [`ExtendedFullViewingKey`].
///
/// Defined in [ZIP 32].
/// It is defined in [the `zcashd` codebase].
///
/// [`ExtendedFullViewingKey`]: zcash_primitives::zip32::ExtendedFullViewingKey
/// [ZIP 32]: https://github.com/zcash/zips/blob/master/zip-0032.rst
/// [the `zcashd` codebase]: https://github.com/zcash/zcash/blob/128d863fb8be39ee294fda397c1ce3ba3b889cb2/src/chainparams.cpp#L494
pub const HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY: &str = "zxviewregtestsapling";
/// The HRP for a Bech32-encoded testnet [`PaymentAddress`].
/// The HRP for a Bech32-encoded regtest [`PaymentAddress`].
///
/// Defined in section 5.6.4 of the [Zcash Protocol Specification].
/// It is defined in [the `zcashd` codebase].
///
/// [`PaymentAddress`]: sapling_crypto::primitives::PaymentAddress
/// [Zcash Protocol Specification]: https://github.com/zcash/zips/blob/master/protocol/protocol.pdf
/// [`PaymentAddress`]: zcash_primitives::primitives::PaymentAddress
/// [the `zcashd` codebase]: https://github.com/zcash/zcash/blob/128d863fb8be39ee294fda397c1ce3ba3b889cb2/src/chainparams.cpp#L493
pub const HRP_SAPLING_PAYMENT_ADDRESS: &str = "zregtestsapling";
/// The prefix for a Base58Check-encoded testnet [`TransparentAddress::PublicKey`].
/// The prefix for a Base58Check-encoded regtest [`TransparentAddress::PublicKey`].
/// Same as the testnet prefix.
///
/// [`TransparentAddress::PublicKey`]: zcash_primitives::legacy::TransparentAddress::PublicKey
pub const B58_PUBKEY_ADDRESS_PREFIX: [u8; 2] = [0x1d, 0x25];
/// The prefix for a Base58Check-encoded testnet [`TransparentAddress::Script`].
/// The prefix for a Base58Check-encoded regtest [`TransparentAddress::Script`].
/// Same as the testnet prefix.
///
/// [`TransparentAddress::Script`]: zcash_primitives::legacy::TransparentAddress::Script
pub const B58_SCRIPT_ADDRESS_PREFIX: [u8; 2] = [0x1c, 0xba];

View File

@@ -1,3 +1,5 @@
//! Constants for the Zcash test network.
/// The testnet coin type for ZEC, as defined by [SLIP 44].
///
/// [SLIP 44]: https://github.com/satoshilabs/slips/blob/master/slip-0044.md
@@ -23,7 +25,7 @@ pub const HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY: &str = "zxviewtestsapling";
///
/// Defined in section 5.6.4 of the [Zcash Protocol Specification].
///
/// [`PaymentAddress`]: sapling_crypto::primitives::PaymentAddress
/// [`PaymentAddress`]: zcash_primitives::primitives::PaymentAddress
/// [Zcash Protocol Specification]: https://github.com/zcash/zips/blob/master/protocol/protocol.pdf
pub const HRP_SAPLING_PAYMENT_ADDRESS: &str = "ztestsapling";

View File

@@ -0,0 +1,76 @@
use pairing::bls12_381::Bls12;
use zcash_primitives::{
note_encryption::{try_sapling_note_decryption, try_sapling_output_recovery, Memo},
primitives::{Note, PaymentAddress},
transaction::Transaction,
zip32::ExtendedFullViewingKey,
JUBJUB,
};
/// A decrypted shielded output.
pub struct DecryptedOutput {
/// The index of the output within [`shielded_outputs`].
///
/// [`shielded_outputs`]: zcash_primitives::transaction::TransactionData
pub index: usize,
/// The note within the output.
pub note: Note<Bls12>,
/// The address the note was sent to.
pub to: PaymentAddress<Bls12>,
/// The memo included with the note.
pub memo: Memo,
/// True if this output was recovered using an [`OutgoingViewingKey`], meaning that
/// this is a logical output of the transaction.
///
/// [`OutgoingViewingKey`]: zcash_primitives::keys::OutgoingViewingKey
pub outgoing: bool,
}
/// Scans a [`Transaction`] for any information that can be decrypted by the set of
/// [`ExtendedFullViewingKey`]s.
pub fn decrypt_transaction(
tx: &Transaction,
extfvks: &[ExtendedFullViewingKey],
) -> Vec<DecryptedOutput> {
let mut decrypted = vec![];
// Cache IncomingViewingKey calculation
let vks: Vec<_> = extfvks
.iter()
.map(|extfvk| (extfvk.fvk.vk.ivk(), extfvk.fvk.ovk))
.collect();
for (index, output) in tx.shielded_outputs.iter().enumerate() {
let epk = match output.ephemeral_key.as_prime_order(&JUBJUB) {
Some(p) => p,
None => continue,
};
for (ivk, ovk) in &vks {
let ((note, to, memo), outgoing) =
match try_sapling_note_decryption(ivk, &epk, &output.cmu, &output.enc_ciphertext) {
Some(ret) => (ret, false),
None => match try_sapling_output_recovery(
ovk,
&output.cv,
&output.cmu,
&epk,
&output.enc_ciphertext,
&output.out_ciphertext,
) {
Some(ret) => (ret, true),
None => continue,
},
};
decrypted.push(DecryptedOutput {
index,
note,
to,
memo,
outgoing,
})
}
}
decrypted
}

View File

@@ -2,17 +2,14 @@
//!
//! Human-Readable Prefixes (HRPs) for Bech32 encodings are located in the [`constants`]
//! module.
//!
//! [`constants`]: crate::constants
use bech32::{self, Error, FromBase32, ToBase32};
use bs58::{self, decode::DecodeError};
use pairing::bls12_381::Bls12;
use std::io::{self, Write};
use zcash_primitives::{
jubjub::edwards,
primitives::{Diversifier, PaymentAddress},
};
use zcash_primitives::{
legacy::TransparentAddress,
primitives::{PaymentAddress},
zip32::{ExtendedFullViewingKey, ExtendedSpendingKey},
JUBJUB,
};
@@ -115,10 +112,11 @@ pub fn decode_extended_full_viewing_key(
/// 0xbc, 0xe5,
/// ]);
///
/// let pa = PaymentAddress {
/// diversifier: Diversifier([0u8; 11]),
/// pk_d: edwards::Point::<Bls12, _>::rand(rng, &JUBJUB).mul_by_cofactor(&JUBJUB),
/// };
/// let pa = PaymentAddress::from_parts(
/// Diversifier([0u8; 11]),
/// edwards::Point::<Bls12, _>::rand(rng, &JUBJUB).mul_by_cofactor(&JUBJUB),
/// )
/// .unwrap();
///
/// assert_eq!(
/// encode_payment_address(HRP_SAPLING_PAYMENT_ADDRESS, &pa),
@@ -126,10 +124,7 @@ pub fn decode_extended_full_viewing_key(
/// );
/// ```
pub fn encode_payment_address(hrp: &str, addr: &PaymentAddress<Bls12>) -> String {
bech32_encode(hrp, |w| {
w.write_all(&addr.diversifier.0)?;
addr.pk_d.write(w)
})
bech32_encode(hrp, |w| w.write_all(&addr.to_bytes()))
}
/// Decodes a [`PaymentAddress`] from a Bech32-encoded string.
@@ -155,10 +150,11 @@ pub fn encode_payment_address(hrp: &str, addr: &PaymentAddress<Bls12>) -> String
/// 0xbc, 0xe5,
/// ]);
///
/// let pa = PaymentAddress {
/// diversifier: Diversifier([0u8; 11]),
/// pk_d: edwards::Point::<Bls12, _>::rand(rng, &JUBJUB).mul_by_cofactor(&JUBJUB),
/// };
/// let pa = PaymentAddress::from_parts(
/// Diversifier([0u8; 11]),
/// edwards::Point::<Bls12, _>::rand(rng, &JUBJUB).mul_by_cofactor(&JUBJUB),
/// )
/// .unwrap();
///
/// assert_eq!(
/// decode_payment_address(
@@ -170,127 +166,16 @@ pub fn encode_payment_address(hrp: &str, addr: &PaymentAddress<Bls12>) -> String
/// ```
pub fn decode_payment_address(hrp: &str, s: &str) -> Result<Option<PaymentAddress<Bls12>>, Error> {
bech32_decode(hrp, s, |data| {
let mut diversifier = Diversifier([0; 11]);
diversifier.0.copy_from_slice(&data[0..11]);
// Check that the diversifier is valid
if diversifier.g_d::<Bls12>(&JUBJUB).is_none() {
if data.len() != 43 {
return None;
}
edwards::Point::<Bls12, _>::read(&data[11..], &JUBJUB)
.ok()?
.as_prime_order(&JUBJUB)
.map(|pk_d| PaymentAddress { pk_d, diversifier })
let mut bytes = [0; 43];
bytes.copy_from_slice(&data);
PaymentAddress::<Bls12>::from_bytes(&bytes, &JUBJUB)
})
}
/// Writes a [`TransparentAddress`] as a Base58Check-encoded string.
///
/// # Examples
///
/// ```
/// use zcash_client_backend::{
/// constants::testnet::{B58_PUBKEY_ADDRESS_PREFIX, B58_SCRIPT_ADDRESS_PREFIX},
/// encoding::encode_transparent_address,
/// };
/// use zcash_primitives::legacy::TransparentAddress;
///
/// assert_eq!(
/// encode_transparent_address(
/// &B58_PUBKEY_ADDRESS_PREFIX,
/// &B58_SCRIPT_ADDRESS_PREFIX,
/// &TransparentAddress::PublicKey([0; 20]),
/// ),
/// "tm9iMLAuYMzJ6jtFLcA7rzUmfreGuKvr7Ma",
/// );
///
/// assert_eq!(
/// encode_transparent_address(
/// &B58_PUBKEY_ADDRESS_PREFIX,
/// &B58_SCRIPT_ADDRESS_PREFIX,
/// &TransparentAddress::Script([0; 20]),
/// ),
/// "t26YoyZ1iPgiMEWL4zGUm74eVWfhyDMXzY2",
/// );
/// ```
pub fn encode_transparent_address(
pubkey_version: &[u8],
script_version: &[u8],
addr: &TransparentAddress,
) -> String {
let decoded = match addr {
TransparentAddress::PublicKey(key_id) => {
let mut decoded = vec![0; pubkey_version.len() + 20];
decoded[..pubkey_version.len()].copy_from_slice(pubkey_version);
decoded[pubkey_version.len()..].copy_from_slice(key_id);
decoded
}
TransparentAddress::Script(script_id) => {
let mut decoded = vec![0; script_version.len() + 20];
decoded[..script_version.len()].copy_from_slice(script_version);
decoded[script_version.len()..].copy_from_slice(script_id);
decoded
}
};
bs58::encode(decoded).with_check().into_string()
}
/// Decodes a [`TransparentAddress`] from a Base58Check-encoded string.
///
/// # Examples
///
/// ```
/// use zcash_client_backend::{
/// constants::testnet::{B58_PUBKEY_ADDRESS_PREFIX, B58_SCRIPT_ADDRESS_PREFIX},
/// encoding::decode_transparent_address,
/// };
/// use zcash_primitives::legacy::TransparentAddress;
///
/// assert_eq!(
/// decode_transparent_address(
/// &B58_PUBKEY_ADDRESS_PREFIX,
/// &B58_SCRIPT_ADDRESS_PREFIX,
/// "tm9iMLAuYMzJ6jtFLcA7rzUmfreGuKvr7Ma",
/// ),
/// Ok(Some(TransparentAddress::PublicKey([0; 20]))),
/// );
///
/// assert_eq!(
/// decode_transparent_address(
/// &B58_PUBKEY_ADDRESS_PREFIX,
/// &B58_SCRIPT_ADDRESS_PREFIX,
/// "t26YoyZ1iPgiMEWL4zGUm74eVWfhyDMXzY2",
/// ),
/// Ok(Some(TransparentAddress::Script([0; 20]))),
/// );
/// ```
pub fn decode_transparent_address(
pubkey_version: &[u8],
script_version: &[u8],
s: &str,
) -> Result<Option<TransparentAddress>, DecodeError> {
let decoded = bs58::decode(s).with_check(None).into_vec()?;
if &decoded[..pubkey_version.len()] == pubkey_version {
if decoded.len() == pubkey_version.len() + 20 {
let mut data = [0; 20];
data.copy_from_slice(&decoded[pubkey_version.len()..]);
Ok(Some(TransparentAddress::PublicKey(data)))
} else {
Ok(None)
}
} else if &decoded[..script_version.len()] == script_version {
if decoded.len() == script_version.len() + 20 {
let mut data = [0; 20];
data.copy_from_slice(&decoded[script_version.len()..]);
Ok(Some(TransparentAddress::Script(data)))
} else {
Ok(None)
}
} else {
Ok(None)
}
}
#[cfg(test)]
mod tests {
use pairing::bls12_381::Bls12;
@@ -300,11 +185,95 @@ mod tests {
use zcash_primitives::{
jubjub::edwards,
primitives::{Diversifier, PaymentAddress},
zip32::ExtendedSpendingKey,
};
use super::{decode_payment_address, encode_payment_address};
use super::{
decode_extended_full_viewing_key, decode_extended_spending_key, decode_payment_address,
encode_extended_full_viewing_key, encode_extended_spending_key, encode_payment_address,
};
use crate::constants;
#[test]
fn extended_spending_key() {
let extsk = ExtendedSpendingKey::master(&[0; 32][..]);
let encoded_main = "secret-extended-key-main1qqqqqqqqqqqqqq8n3zjjmvhhr854uy3qhpda3ml34haf0x388z5r7h4st4kpsf6qysqws3xh6qmha7gna72fs2n4clnc9zgyd22s658f65pex4exe56qjk5pqj9vfdq7dfdhjc2rs9jdwq0zl99uwycyrxzp86705rk687spn44e2uhm7h0hsagfvkk4n7n6nfer6u57v9cac84t7nl2zth0xpyfeg0w2p2wv2yn6jn923aaz0vdaml07l60ahapk6efchyxwysrvjs87qvlj";
let encoded_test = "secret-extended-key-test1qqqqqqqqqqqqqq8n3zjjmvhhr854uy3qhpda3ml34haf0x388z5r7h4st4kpsf6qysqws3xh6qmha7gna72fs2n4clnc9zgyd22s658f65pex4exe56qjk5pqj9vfdq7dfdhjc2rs9jdwq0zl99uwycyrxzp86705rk687spn44e2uhm7h0hsagfvkk4n7n6nfer6u57v9cac84t7nl2zth0xpyfeg0w2p2wv2yn6jn923aaz0vdaml07l60ahapk6efchyxwysrvjsvzyw8j";
assert_eq!(
encode_extended_spending_key(
constants::mainnet::HRP_SAPLING_EXTENDED_SPENDING_KEY,
&extsk
),
encoded_main
);
assert_eq!(
decode_extended_spending_key(
constants::mainnet::HRP_SAPLING_EXTENDED_SPENDING_KEY,
encoded_main
)
.unwrap(),
Some(extsk.clone())
);
assert_eq!(
encode_extended_spending_key(
constants::testnet::HRP_SAPLING_EXTENDED_SPENDING_KEY,
&extsk
),
encoded_test
);
assert_eq!(
decode_extended_spending_key(
constants::testnet::HRP_SAPLING_EXTENDED_SPENDING_KEY,
encoded_test
)
.unwrap(),
Some(extsk)
);
}
#[test]
fn extended_full_viewing_key() {
let extfvk = (&ExtendedSpendingKey::master(&[0; 32][..])).into();
let encoded_main = "zxviews1qqqqqqqqqqqqqq8n3zjjmvhhr854uy3qhpda3ml34haf0x388z5r7h4st4kpsf6qy3zw4wc246aw9rlfyg5ndlwvne7mwdq0qe6vxl42pqmcf8pvmmd5slmjxduqa9evgej6wa3th2505xq4nggrxdm93rxk4rpdjt5nmq2vn44e2uhm7h0hsagfvkk4n7n6nfer6u57v9cac84t7nl2zth0xpyfeg0w2p2wv2yn6jn923aaz0vdaml07l60ahapk6efchyxwysrvjsxmansf";
let encoded_test = "zxviewtestsapling1qqqqqqqqqqqqqq8n3zjjmvhhr854uy3qhpda3ml34haf0x388z5r7h4st4kpsf6qy3zw4wc246aw9rlfyg5ndlwvne7mwdq0qe6vxl42pqmcf8pvmmd5slmjxduqa9evgej6wa3th2505xq4nggrxdm93rxk4rpdjt5nmq2vn44e2uhm7h0hsagfvkk4n7n6nfer6u57v9cac84t7nl2zth0xpyfeg0w2p2wv2yn6jn923aaz0vdaml07l60ahapk6efchyxwysrvjs8evfkz";
assert_eq!(
encode_extended_full_viewing_key(
constants::mainnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
&extfvk
),
encoded_main
);
assert_eq!(
decode_extended_full_viewing_key(
constants::mainnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
encoded_main
)
.unwrap(),
Some(extfvk.clone())
);
assert_eq!(
encode_extended_full_viewing_key(
constants::testnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
&extfvk
),
encoded_test
);
assert_eq!(
decode_extended_full_viewing_key(
constants::testnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
encoded_test
)
.unwrap(),
Some(extfvk)
);
}
#[test]
fn payment_address() {
let rng = &mut XorShiftRng::from_seed([
@@ -312,10 +281,11 @@ mod tests {
0xbc, 0xe5,
]);
let addr = PaymentAddress {
diversifier: Diversifier([0u8; 11]),
pk_d: edwards::Point::<Bls12, _>::rand(rng, &JUBJUB).mul_by_cofactor(&JUBJUB),
};
let addr = PaymentAddress::from_parts(
Diversifier([0u8; 11]),
edwards::Point::<Bls12, _>::rand(rng, &JUBJUB).mul_by_cofactor(&JUBJUB),
)
.unwrap();
let encoded_main =
"zs1qqqqqqqqqqqqqqqqqrjq05nyfku05msvu49mawhg6kr0wwljahypwyk2h88z6975u563j8nfaxd";
@@ -356,10 +326,11 @@ mod tests {
0xbc, 0xe5,
]);
let addr = PaymentAddress {
diversifier: Diversifier([1u8; 11]),
pk_d: edwards::Point::<Bls12, _>::rand(rng, &JUBJUB).mul_by_cofactor(&JUBJUB),
};
let addr = PaymentAddress::from_parts(
Diversifier([1u8; 11]),
edwards::Point::<Bls12, _>::rand(rng, &JUBJUB).mul_by_cofactor(&JUBJUB),
)
.unwrap();
let encoded_main =
encode_payment_address(constants::mainnet::HRP_SAPLING_PAYMENT_ADDRESS, &addr);

View File

@@ -5,6 +5,10 @@ use zcash_primitives::zip32::{ChildIndex, ExtendedSpendingKey};
/// Derives the ZIP 32 [`ExtendedSpendingKey`] for a given coin type and account from the
/// given seed.
///
/// # Panics
///
/// Panics if `seed` is shorter than 32 bytes.
///
/// # Examples
///
/// ```
@@ -13,6 +17,10 @@ use zcash_primitives::zip32::{ChildIndex, ExtendedSpendingKey};
/// let extsk = spending_key(&[0; 32][..], COIN_TYPE, 0);
/// ```
pub fn spending_key(seed: &[u8], coin_type: u32, account: u32) -> ExtendedSpendingKey {
if seed.len() < 32 {
panic!("ZIP 32 seeds MUST be at least 32 bytes");
}
ExtendedSpendingKey::from_path(
&ExtendedSpendingKey::master(&seed),
&[
@@ -22,3 +30,14 @@ pub fn spending_key(seed: &[u8], coin_type: u32, account: u32) -> ExtendedSpendi
],
)
}
#[cfg(test)]
mod tests {
use super::spending_key;
#[test]
#[should_panic]
fn spending_key_panics_on_short_seed() {
let _ = spending_key(&[0; 31][..], 0, 0);
}
}

View File

@@ -3,9 +3,15 @@
//! `zcash_client_backend` contains Rust structs and traits for creating shielded Zcash
//! light clients.
// Catch documentation errors caused by code changes.
#![deny(intra_doc_link_resolution_failure)]
pub mod constants;
mod decrypt;
pub mod encoding;
pub mod keys;
pub mod proto;
pub mod wallet;
pub mod welding_rig;
pub use decrypt::{decrypt_transaction, DecryptedOutput};

View File

@@ -1,6 +1,6 @@
//! Generated code for handling light client protobuf structs.
use ff::{PrimeField, PrimeFieldRepr};
use ff::{PrimeField};
use pairing::bls12_381::{Bls12, Fr, FrRepr};
use zcash_primitives::{
block::{BlockHash, BlockHeader},
@@ -67,8 +67,8 @@ impl compact_formats::CompactOutput {
/// [`CompactOutput.cmu`]: #structfield.cmu
pub fn cmu(&self) -> Result<Fr, ()> {
let mut repr = FrRepr::default();
repr.read_le(&self.cmu[..]).map_err(|_| ())?;
Fr::from_repr(repr).map_err(|_| ())
repr.as_mut().copy_from_slice(&self.cmu[..]);
Fr::from_repr(repr).ok_or(())
}
/// Returns the ephemeral public key for this output.

View File

@@ -36,7 +36,7 @@ fn scan_output(
let ct = output.ciphertext;
// Increment tree and witnesses
let node = Node::new(cmu.into_repr());
let node = Node::new(cmu.to_repr());
for witness in existing_witnesses {
witness.append(node).unwrap();
}
@@ -134,12 +134,11 @@ pub fn scan_block(
// mutable references to wtxs for too long.
let mut block_witnesses: Vec<_> = wtxs
.iter_mut()
.map(|tx| {
.flat_map(|tx| {
tx.shielded_outputs
.iter_mut()
.map(|output| &mut output.witness)
})
.flatten()
.collect();
for to_scan in tx.outputs.into_iter().enumerate() {
@@ -184,10 +183,9 @@ pub fn scan_block(
#[cfg(test)]
mod tests {
use ff::{Field, PrimeField, PrimeFieldRepr};
use ff::{Field, PrimeField};
use pairing::bls12_381::{Bls12, Fr};
use rand_core::RngCore;
use rand_os::OsRng;
use rand_core::{OsRng, RngCore};
use zcash_primitives::{
jubjub::{fs::Fs, FixedGenerators, JubjubParams, ToUniform},
merkle_tree::CommitmentTree,
@@ -209,9 +207,7 @@ mod tests {
};
let fake_cmu = {
let fake_cmu = Fr::random(rng);
let mut bytes = vec![];
fake_cmu.into_repr().write_le(&mut bytes).unwrap();
bytes
fake_cmu.to_repr().as_ref().to_owned()
};
let fake_epk = {
let mut buffer = vec![0; 64];
@@ -254,8 +250,8 @@ mod tests {
// Create a fake Note for the account
let mut rng = OsRng;
let note = Note {
g_d: to.diversifier.g_d::<Bls12>(&JUBJUB).unwrap(),
pk_d: to.pk_d.clone(),
g_d: to.diversifier().g_d::<Bls12>(&JUBJUB).unwrap(),
pk_d: to.pk_d().clone(),
value: value.into(),
r: Fs::random(&mut rng),
};
@@ -266,8 +262,7 @@ mod tests {
Memo::default(),
&mut rng,
);
let mut cmu = vec![];
note.cm(&JUBJUB).into_repr().write_le(&mut cmu).unwrap();
let cmu = note.cm(&JUBJUB).to_repr().as_ref().to_owned();
let mut epk = vec![];
encryptor.epk().write(&mut epk).unwrap();
let enc_ciphertext = encryptor.encrypt_note_plaintext();