Merge remote-tracking branch 'upstream/master' into autoshield-poc-reorder
This commit is contained in:
commit
6cf0749ac9
|
@ -0,0 +1,14 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: github-actions
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
timezone: Etc/UTC
|
||||
open-pull-requests-limit: 10
|
||||
reviewers:
|
||||
- str4d
|
||||
assignees:
|
||||
- str4d
|
||||
labels:
|
||||
- "A-CI"
|
|
@ -163,9 +163,7 @@ jobs:
|
|||
command: tarpaulin
|
||||
args: --all-features --release --timeout 600 --out Xml
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v1
|
||||
with:
|
||||
token: ${{secrets.CODECOV_TOKEN}}
|
||||
uses: codecov/codecov-action@v2.1.0
|
||||
|
||||
doc-links:
|
||||
name: Intra-doc links
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
[workspace]
|
||||
members = [
|
||||
"components/equihash",
|
||||
"components/f4jumble",
|
||||
"components/zcash_address",
|
||||
"components/zcash_encoding",
|
||||
"components/zcash_note_encryption",
|
||||
"zcash_client_backend",
|
||||
"zcash_client_sqlite",
|
||||
|
@ -18,10 +20,7 @@ codegen-units = 1
|
|||
|
||||
[patch.crates-io]
|
||||
# In development.
|
||||
halo2 = { git = "https://github.com/zcash/halo2.git", rev = "27c4187673a9c6ade13fbdbd4f20955530c22d7f" }
|
||||
orchard = { git = "https://github.com/zcash/orchard.git", rev = "d0baa18fc6105df4a7847de2b6dc50c5919b3123" }
|
||||
orchard = { git = "https://github.com/zcash/orchard.git", rev = "2c8241f25b943aa05203eacf9905db117c69bd29" }
|
||||
incrementalmerkletree = { git = "https://github.com/zcash/incrementalmerkletree.git", rev = "b7bd6246122a6e9ace8edb51553fbf5228906cbb" }
|
||||
zcash_encoding = { path = "components/zcash_encoding" }
|
||||
zcash_note_encryption = { path = "components/zcash_note_encryption" }
|
||||
|
||||
# Unreleased
|
||||
jubjub = { git = "https://github.com/zkcrypto/jubjub.git", rev = "96ab4162b83303378eae32a326b54d88b75bffc2" }
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
[package]
|
||||
name = "f4jumble"
|
||||
description = "Implementation of Zcash's F4Jumble algorithm"
|
||||
version = "0.0.0"
|
||||
authors = [
|
||||
"Jack Grigg <jack@electriccoin.co>",
|
||||
"Kris Nuttycombe <kris@electriccoin.co>",
|
||||
"Daira Hopwood <daira@electriccoin.co>",
|
||||
]
|
||||
homepage = "https://github.com/zcash/librustzcash"
|
||||
repository = "https://github.com/zcash/librustzcash"
|
||||
readme = "README.md"
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
blake2b_simd = "0.5"
|
||||
|
||||
[dev-dependencies]
|
||||
proptest = "1"
|
|
@ -0,0 +1,202 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2021 Electric Coin Company
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -0,0 +1,24 @@
|
|||
# f4jumble
|
||||
|
||||
An implementation of the F4Jumble algorithm, an unkeyed variable-width
|
||||
permutation.
|
||||
|
||||
F4Jumble is used by Zcash Unified Addresses and Unified Viewing Keys to
|
||||
prevent certain kinds of malleation attacks, and is specified by [ZIP 316](https://zips.z.cash/zip316).
|
||||
|
||||
## License
|
||||
|
||||
Licensed under either of
|
||||
|
||||
* 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.
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally
|
||||
submitted for inclusion in the work by you, as defined in the Apache-2.0
|
||||
license, shall be dual licensed as above, without any additional terms or
|
||||
conditions.
|
|
@ -4,13 +4,15 @@ use std::ops::RangeInclusive;
|
|||
|
||||
#[cfg(test)]
|
||||
mod test_vectors;
|
||||
#[cfg(test)]
|
||||
mod test_vectors_long;
|
||||
|
||||
const VALID_LENGTH: RangeInclusive<usize> = 48..=16448;
|
||||
const VALID_LENGTH: RangeInclusive<usize> = 48..=4194368;
|
||||
|
||||
macro_rules! H_PERS {
|
||||
( $i:expr ) => {
|
||||
[
|
||||
85, 65, 95, 70, 52, 74, 117, 109, 98, 108, 101, 95, 72, 95, $i, 0,
|
||||
85, 65, 95, 70, 52, 74, 117, 109, 98, 108, 101, 95, 72, $i, 0, 0,
|
||||
]
|
||||
};
|
||||
}
|
||||
|
@ -18,7 +20,22 @@ macro_rules! H_PERS {
|
|||
macro_rules! G_PERS {
|
||||
( $i:expr, $j:expr ) => {
|
||||
[
|
||||
85, 65, 95, 70, 52, 74, 117, 109, 98, 108, 101, 95, 71, 95, $i, $j,
|
||||
85,
|
||||
65,
|
||||
95,
|
||||
70,
|
||||
52,
|
||||
74,
|
||||
117,
|
||||
109,
|
||||
98,
|
||||
108,
|
||||
101,
|
||||
95,
|
||||
71,
|
||||
$i,
|
||||
($j & 0xFF) as u8,
|
||||
($j >> 8) as u8,
|
||||
]
|
||||
};
|
||||
}
|
||||
|
@ -49,7 +66,7 @@ impl Hashes {
|
|||
.flat_map(|j| {
|
||||
Blake2bParams::new()
|
||||
.hash_length(OUTBYTES)
|
||||
.personal(&G_PERS!(i, j as u8))
|
||||
.personal(&G_PERS!(i, j as u16))
|
||||
.hash(u)
|
||||
.as_ref()
|
||||
.to_vec()
|
||||
|
@ -106,22 +123,28 @@ pub fn f4jumble_inv(c: &[u8]) -> Option<Vec<u8>> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use blake2b_simd::blake2b;
|
||||
use proptest::collection::vec;
|
||||
use proptest::prelude::*;
|
||||
|
||||
use super::{f4jumble, f4jumble_inv, test_vectors::test_vectors, VALID_LENGTH};
|
||||
use super::{
|
||||
f4jumble, f4jumble_inv, test_vectors::test_vectors, test_vectors_long, VALID_LENGTH,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn h_pers() {
|
||||
assert_eq!(&H_PERS!(7), b"UA_F4Jumble_H_\x07\x00");
|
||||
assert_eq!(&H_PERS!(7), b"UA_F4Jumble_H\x07\x00\x00");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn g_pers() {
|
||||
assert_eq!(&G_PERS!(7, 13), b"UA_F4Jumble_G_\x07\x0d");
|
||||
assert_eq!(&G_PERS!(7, 13), b"UA_F4Jumble_G\x07\x0d\x00");
|
||||
assert_eq!(&G_PERS!(7, 65535), b"UA_F4Jumble_G\x07\xff\xff");
|
||||
}
|
||||
|
||||
proptest! {
|
||||
#![proptest_config(ProptestConfig::with_cases(5))]
|
||||
|
||||
#[test]
|
||||
fn f4jumble_roundtrip(msg in vec(any::<u8>(), VALID_LENGTH)) {
|
||||
let jumbled = f4jumble(&msg).unwrap();
|
||||
|
@ -152,4 +175,15 @@ mod tests {
|
|||
assert_eq!(unjumbled, v.normal);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn f4jumble_check_vectors_long() {
|
||||
for v in test_vectors_long::TEST_VECTORS {
|
||||
let normal: Vec<u8> = (0..v.length).map(|i| i as u8).collect();
|
||||
let jumbled = f4jumble(&normal).unwrap();
|
||||
assert_eq!(blake2b(&jumbled).as_bytes(), v.jumbled_hash);
|
||||
let unjumbled = f4jumble_inv(&jumbled).unwrap();
|
||||
assert_eq!(unjumbled, normal);
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,28 @@
|
|||
pub(crate) struct TestVector {
|
||||
pub(crate) length: usize,
|
||||
pub(crate) jumbled_hash: &'static [u8],
|
||||
}
|
||||
|
||||
// From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/f4jumble_long.py
|
||||
pub(crate) const TEST_VECTORS: &[TestVector] = &[
|
||||
TestVector {
|
||||
length: 3246395,
|
||||
jumbled_hash: &[
|
||||
0x3f, 0xc2, 0xec, 0xdf, 0xb6, 0x86, 0x96, 0x57, 0x1d, 0x89, 0xe8, 0xbe, 0xdd, 0xb6,
|
||||
0x47, 0xe6, 0x99, 0x0b, 0x63, 0xa0, 0x17, 0x1c, 0x36, 0x44, 0x22, 0x73, 0xd6, 0x87,
|
||||
0xbd, 0x99, 0x25, 0x7e, 0xc5, 0x00, 0x2e, 0xc8, 0x19, 0x78, 0x01, 0xb6, 0x21, 0x73,
|
||||
0x2d, 0x6b, 0x05, 0xb8, 0xd7, 0x0f, 0x68, 0x86, 0x20, 0xa4, 0xc0, 0x88, 0x73, 0xc1,
|
||||
0x2e, 0x44, 0x39, 0xa0, 0x12, 0x7d, 0xc9, 0x45,
|
||||
],
|
||||
},
|
||||
TestVector {
|
||||
length: 4194368,
|
||||
jumbled_hash: &[
|
||||
0xa5, 0xf1, 0x8f, 0x16, 0x3e, 0x59, 0x8d, 0x4a, 0xdb, 0x6e, 0xa7, 0x24, 0x80, 0x57,
|
||||
0xe2, 0x4c, 0x1b, 0x61, 0xf2, 0x9b, 0x33, 0xb7, 0xab, 0xcd, 0xab, 0xd4, 0x20, 0xa0,
|
||||
0xf2, 0xee, 0x6c, 0x3e, 0xd3, 0x13, 0x94, 0x65, 0x2f, 0x28, 0xb5, 0x9c, 0x44, 0xd3,
|
||||
0xea, 0x9e, 0xcf, 0x85, 0xf4, 0xd5, 0x01, 0xe6, 0xaa, 0xc1, 0x4d, 0xf2, 0x88, 0xef,
|
||||
0xd6, 0x2c, 0xf8, 0x0d, 0x18, 0x29, 0xd0, 0x25,
|
||||
],
|
||||
},
|
||||
];
|
|
@ -15,8 +15,11 @@ edition = "2018"
|
|||
bech32 = "0.8"
|
||||
blake2b_simd = "0.5"
|
||||
bs58 = { version = "0.4", features = ["check"] }
|
||||
f4jumble = { version = "0.0", path = "../f4jumble" }
|
||||
zcash_encoding = { version = "0.0", path = "../zcash_encoding" }
|
||||
|
||||
[dev-dependencies]
|
||||
assert_matches = "1.3.0"
|
||||
proptest = "1"
|
||||
|
||||
[lib]
|
||||
|
|
|
@ -18,7 +18,7 @@ pub enum ParseError {
|
|||
impl From<unified::ParseError> for ParseError {
|
||||
fn from(e: unified::ParseError) -> Self {
|
||||
match e {
|
||||
unified::ParseError::InvalidEncoding => Self::InvalidEncoding,
|
||||
unified::ParseError::InvalidEncoding(_) => Self::InvalidEncoding,
|
||||
_ => Self::Unified(e),
|
||||
}
|
||||
}
|
||||
|
@ -227,21 +227,21 @@ mod tests {
|
|||
#[test]
|
||||
fn unified() {
|
||||
encoding(
|
||||
"u175h4qsgd8gujkevz283ka89ul6r2kr25xvachlt5w5srewdwcjacdtm3ku06jazzwk2klezj3kfy2jc9p65l5fgvjhekmnd4myk2m7xn",
|
||||
"u1qpatys4zruk99pg59gcscrt7y6akvl9vrhcfyhm9yxvxz7h87q6n8cgrzzpe9zru68uq39uhmlpp5uefxu0su5uqyqfe5zp3tycn0ecl",
|
||||
ZcashAddress {
|
||||
net: Network::Main,
|
||||
kind: AddressKind::Unified(unified::Address(vec![unified::Receiver::Sapling([0; 43])])),
|
||||
},
|
||||
);
|
||||
encoding(
|
||||
"utest193cmy6pcjrw6cg8rqcxgq6z2095a2mc0hqu0g0gvnlf83em0szx23qtv9722s6qkssz80try4tynp73u9gee3zskye0ztzdz0snrxw7n",
|
||||
"utest10c5kutapazdnf8ztl3pu43nkfsjx89fy3uuff8tsmxm6s86j37pe7uz94z5jhkl49pqe8yz75rlsaygexk6jpaxwx0esjr8wm5ut7d5s",
|
||||
ZcashAddress {
|
||||
net: Network::Test,
|
||||
kind: AddressKind::Unified(unified::Address(vec![unified::Receiver::Sapling([0; 43])])),
|
||||
},
|
||||
);
|
||||
encoding(
|
||||
"uregtest1dl4mka5saz8xwnf0pttr637jx6su0nejfhzcz3metcmqyzdgktsmm09ese6ew794xqcyp6476nuspvdvx2xk6gn2euvu7fdmrvwl87zx",
|
||||
"uregtest15xk7vj4grjkay6mnfl93dhsflc2yeunhxwdh38rul0rq3dfhzzxgm5szjuvtqdha4t4p2q02ks0jgzrhjkrav70z9xlvq0plpcjkd5z3",
|
||||
ZcashAddress {
|
||||
net: Network::Regtest,
|
||||
kind: AddressKind::Unified(unified::Address(vec![unified::Receiver::Sapling([0; 43])])),
|
||||
|
|
|
@ -3,12 +3,11 @@ use std::collections::HashSet;
|
|||
use std::convert::{TryFrom, TryInto};
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::iter;
|
||||
use std::io::Write;
|
||||
use zcash_encoding::CompactSize;
|
||||
|
||||
use crate::kind;
|
||||
|
||||
mod f4jumble;
|
||||
|
||||
/// The HRP for a Bech32m-encoded mainnet Unified Address.
|
||||
///
|
||||
/// Defined in [ZIP 316][zip-0316].
|
||||
|
@ -34,7 +33,7 @@ pub enum Typecode {
|
|||
P2sh,
|
||||
Sapling,
|
||||
Orchard,
|
||||
Unknown(u8),
|
||||
Unknown(u32),
|
||||
}
|
||||
|
||||
impl Ord for Typecode {
|
||||
|
@ -75,19 +74,22 @@ impl PartialOrd for Typecode {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<u8> for Typecode {
|
||||
fn from(typecode: u8) -> Self {
|
||||
impl TryFrom<u32> for Typecode {
|
||||
type Error = ParseError;
|
||||
|
||||
fn try_from(typecode: u32) -> Result<Self, Self::Error> {
|
||||
match typecode {
|
||||
0x00 => Typecode::P2pkh,
|
||||
0x01 => Typecode::P2sh,
|
||||
0x02 => Typecode::Sapling,
|
||||
0x03 => Typecode::Orchard,
|
||||
_ => Typecode::Unknown(typecode),
|
||||
0x00 => Ok(Typecode::P2pkh),
|
||||
0x01 => Ok(Typecode::P2sh),
|
||||
0x02 => Ok(Typecode::Sapling),
|
||||
0x03 => Ok(Typecode::Orchard),
|
||||
0x04..=0x02000000 => Ok(Typecode::Unknown(typecode)),
|
||||
0x02000001..=u32::MAX => Err(ParseError::InvalidTypecodeValue(typecode as u64)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Typecode> for u8 {
|
||||
impl From<Typecode> for u32 {
|
||||
fn from(t: Typecode) -> Self {
|
||||
match t {
|
||||
Typecode::P2pkh => 0x00,
|
||||
|
@ -114,8 +116,10 @@ pub enum ParseError {
|
|||
BothP2phkAndP2sh,
|
||||
/// The unified address contains a duplicated typecode.
|
||||
DuplicateTypecode(Typecode),
|
||||
/// The parsed typecode exceeds the maximum allowed CompactSize value.
|
||||
InvalidTypecodeValue(u64),
|
||||
/// The string is an invalid encoding.
|
||||
InvalidEncoding,
|
||||
InvalidEncoding(String),
|
||||
/// The unified address only contains transparent receivers.
|
||||
OnlyTransparent,
|
||||
}
|
||||
|
@ -124,10 +128,9 @@ impl fmt::Display for ParseError {
|
|||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
ParseError::BothP2phkAndP2sh => write!(f, "UA contains both P2PKH and P2SH receivers"),
|
||||
ParseError::DuplicateTypecode(typecode) => {
|
||||
write!(f, "Duplicate typecode {}", u8::from(*typecode))
|
||||
}
|
||||
ParseError::InvalidEncoding => write!(f, "Invalid encoding"),
|
||||
ParseError::DuplicateTypecode(c) => write!(f, "Duplicate typecode {}", u32::from(*c)),
|
||||
ParseError::InvalidTypecodeValue(v) => write!(f, "Typecode value out of range {}", v),
|
||||
ParseError::InvalidEncoding(msg) => write!(f, "Invalid encoding: {}", msg),
|
||||
ParseError::OnlyTransparent => write!(f, "UA only contains transparent receivers"),
|
||||
}
|
||||
}
|
||||
|
@ -142,7 +145,7 @@ pub enum Receiver {
|
|||
Sapling(kind::sapling::Data),
|
||||
P2pkh(kind::p2pkh::Data),
|
||||
P2sh(kind::p2sh::Data),
|
||||
Unknown { typecode: u8, data: Vec<u8> },
|
||||
Unknown { typecode: u32, data: Vec<u8> },
|
||||
}
|
||||
|
||||
impl cmp::Ord for Receiver {
|
||||
|
@ -160,11 +163,11 @@ impl cmp::PartialOrd for Receiver {
|
|||
}
|
||||
}
|
||||
|
||||
impl TryFrom<(u8, &[u8])> for Receiver {
|
||||
impl TryFrom<(u32, &[u8])> for Receiver {
|
||||
type Error = ParseError;
|
||||
|
||||
fn try_from((typecode, addr): (u8, &[u8])) -> Result<Self, Self::Error> {
|
||||
match typecode.into() {
|
||||
fn try_from((typecode, addr): (u32, &[u8])) -> Result<Self, Self::Error> {
|
||||
match typecode.try_into()? {
|
||||
Typecode::P2pkh => addr.try_into().map(Receiver::P2pkh),
|
||||
Typecode::P2sh => addr.try_into().map(Receiver::P2sh),
|
||||
Typecode::Sapling => addr.try_into().map(Receiver::Sapling),
|
||||
|
@ -174,7 +177,9 @@ impl TryFrom<(u8, &[u8])> for Receiver {
|
|||
data: addr.to_vec(),
|
||||
}),
|
||||
}
|
||||
.map_err(|_| ParseError::InvalidEncoding)
|
||||
.map_err(|e| {
|
||||
ParseError::InvalidEncoding(format!("Invalid address for typecode {}: {}", typecode, e))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -208,37 +213,67 @@ impl TryFrom<(&str, &[u8])> for Address {
|
|||
type Error = ParseError;
|
||||
|
||||
fn try_from((hrp, buf): (&str, &[u8])) -> Result<Self, Self::Error> {
|
||||
let encoded = f4jumble::f4jumble_inv(buf).ok_or(ParseError::InvalidEncoding)?;
|
||||
fn read_receiver(mut cursor: &mut std::io::Cursor<&[u8]>) -> Result<Receiver, ParseError> {
|
||||
let typecode = CompactSize::read(&mut cursor)
|
||||
.map(|v| u32::try_from(v).expect("CompactSize::read enforces MAX_SIZE limit"))
|
||||
.map_err(|e| {
|
||||
ParseError::InvalidEncoding(format!(
|
||||
"Failed to deserialize CompactSize-encoded typecode {}",
|
||||
e
|
||||
))
|
||||
})?;
|
||||
let length = CompactSize::read(&mut cursor).map_err(|e| {
|
||||
ParseError::InvalidEncoding(format!(
|
||||
"Failed to deserialize CompactSize-encoded length {}",
|
||||
e
|
||||
))
|
||||
})?;
|
||||
let addr_end = cursor.position().checked_add(length).ok_or_else(|| {
|
||||
ParseError::InvalidEncoding(format!(
|
||||
"Length value {} caused an overflow error",
|
||||
length
|
||||
))
|
||||
})?;
|
||||
let buf = cursor.get_ref();
|
||||
if (buf.len() as u64) < addr_end {
|
||||
return Err(ParseError::InvalidEncoding(format!(
|
||||
"Truncated: unable to read {} bytes of address data",
|
||||
length
|
||||
)));
|
||||
}
|
||||
let result = Receiver::try_from((
|
||||
typecode,
|
||||
&buf[cursor.position() as usize..addr_end as usize],
|
||||
));
|
||||
cursor.set_position(addr_end);
|
||||
result
|
||||
}
|
||||
|
||||
let encoded = f4jumble::f4jumble_inv(buf)
|
||||
.ok_or_else(|| ParseError::InvalidEncoding("F4Jumble decoding failed".to_owned()))?;
|
||||
|
||||
// Validate and strip trailing padding bytes.
|
||||
if hrp.len() > 16 {
|
||||
return Err(ParseError::InvalidEncoding);
|
||||
return Err(ParseError::InvalidEncoding(
|
||||
"Invalid human-readable part".to_owned(),
|
||||
));
|
||||
}
|
||||
let mut expected_padding = [0; PADDING_LEN];
|
||||
expected_padding[0..hrp.len()].copy_from_slice(hrp.as_bytes());
|
||||
let encoded = match encoded.split_at(encoded.len() - PADDING_LEN) {
|
||||
(encoded, tail) if tail == expected_padding => Ok(encoded),
|
||||
_ => Err(ParseError::InvalidEncoding),
|
||||
_ => Err(ParseError::InvalidEncoding(
|
||||
"Invalid padding bytes".to_owned(),
|
||||
)),
|
||||
}?;
|
||||
|
||||
iter::repeat(())
|
||||
.scan(encoded, |encoded, _| match encoded {
|
||||
// Base case: we've parsed the full encoding.
|
||||
[] => None,
|
||||
// The raw encoding of a Unified Address is a concatenation of:
|
||||
// - typecode: byte
|
||||
// - length: byte
|
||||
// - addr: byte[length]
|
||||
[typecode, length, data @ ..] if data.len() >= *length as usize => {
|
||||
let (addr, rest) = data.split_at(*length as usize);
|
||||
*encoded = rest;
|
||||
Some(Receiver::try_from((*typecode, addr)))
|
||||
}
|
||||
// The encoding is truncated.
|
||||
_ => Some(Err(ParseError::InvalidEncoding)),
|
||||
})
|
||||
.collect::<Result<_, _>>()
|
||||
.and_then(|receivers: Vec<Receiver>| receivers.try_into())
|
||||
let mut cursor = std::io::Cursor::new(encoded);
|
||||
let mut result = vec![];
|
||||
while cursor.position() < encoded.len().try_into().unwrap() {
|
||||
result.push(read_receiver(&mut cursor)?);
|
||||
}
|
||||
assert_eq!(cursor.position(), encoded.len().try_into().unwrap());
|
||||
result.try_into()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -272,26 +307,25 @@ impl TryFrom<Vec<Receiver>> for Address {
|
|||
impl Address {
|
||||
/// Returns the raw encoding of this Unified Address.
|
||||
pub(crate) fn to_bytes(&self, hrp: &str) -> Vec<u8> {
|
||||
assert!(hrp.len() <= 16);
|
||||
assert!(hrp.len() <= PADDING_LEN);
|
||||
|
||||
let encoded: Vec<_> = self
|
||||
.0
|
||||
.iter()
|
||||
.flat_map(|receiver| {
|
||||
let addr = receiver.addr();
|
||||
// Holds by construction.
|
||||
assert!(addr.len() < 256);
|
||||
let mut writer = std::io::Cursor::new(Vec::new());
|
||||
for receiver in &self.0 {
|
||||
let addr = receiver.addr();
|
||||
CompactSize::write(
|
||||
&mut writer,
|
||||
<u32>::from(receiver.typecode()).try_into().unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
CompactSize::write(&mut writer, addr.len()).unwrap();
|
||||
writer.write_all(addr).unwrap();
|
||||
}
|
||||
|
||||
iter::empty()
|
||||
.chain(Some(receiver.typecode().into()))
|
||||
.chain(Some(addr.len() as u8))
|
||||
.chain(addr.iter().cloned())
|
||||
})
|
||||
.chain(hrp.as_bytes().iter().cloned())
|
||||
.chain(iter::repeat(0).take(PADDING_LEN - hrp.len()))
|
||||
.collect();
|
||||
let mut padding = [0u8; PADDING_LEN];
|
||||
padding[0..hrp.len()].copy_from_slice(&hrp.as_bytes());
|
||||
writer.write_all(&padding).unwrap();
|
||||
|
||||
f4jumble::f4jumble(&encoded).unwrap()
|
||||
f4jumble::f4jumble(&writer.into_inner()).unwrap()
|
||||
}
|
||||
|
||||
/// Returns the receivers contained within this address, sorted in preference order.
|
||||
|
@ -312,8 +346,12 @@ impl Address {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) mod test_vectors;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use assert_matches::assert_matches;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use proptest::{
|
||||
|
@ -383,7 +421,9 @@ mod tests {
|
|||
];
|
||||
assert_eq!(
|
||||
Address::try_from((MAINNET, &invalid_padding[..])),
|
||||
Err(ParseError::InvalidEncoding)
|
||||
Err(ParseError::InvalidEncoding(
|
||||
"Invalid padding bytes".to_owned()
|
||||
))
|
||||
);
|
||||
|
||||
// Short padding (padded to 15 bytes instead of 16)
|
||||
|
@ -396,7 +436,9 @@ mod tests {
|
|||
];
|
||||
assert_eq!(
|
||||
Address::try_from((MAINNET, &truncated_padding[..])),
|
||||
Err(ParseError::InvalidEncoding)
|
||||
Err(ParseError::InvalidEncoding(
|
||||
"Invalid padding bytes".to_owned()
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -417,9 +459,9 @@ mod tests {
|
|||
0xb2, 0x63, 0x80, 0xbb, 0xdc, 0x12, 0x08, 0x48, 0x28, 0x8f, 0x1c, 0x9e, 0xc3, 0x42,
|
||||
0xc6, 0x5e, 0x68, 0xa2, 0x78, 0x6c, 0x9e,
|
||||
];
|
||||
assert_eq!(
|
||||
assert_matches!(
|
||||
Address::try_from((MAINNET, &truncated_sapling_data[..])),
|
||||
Err(ParseError::InvalidEncoding)
|
||||
Err(ParseError::InvalidEncoding(_))
|
||||
);
|
||||
|
||||
// - Truncated after the typecode of the Sapling receiver.
|
||||
|
@ -430,9 +472,9 @@ mod tests {
|
|||
0x4c, 0xdf, 0x36, 0xa1, 0xac, 0x82, 0x57, 0xed, 0x0c, 0x98, 0x49, 0x8f, 0x49, 0x7e,
|
||||
0xe6, 0x70, 0x36, 0x5b, 0x7b, 0x9e,
|
||||
];
|
||||
assert_eq!(
|
||||
assert_matches!(
|
||||
Address::try_from((MAINNET, &truncated_after_sapling_typecode[..])),
|
||||
Err(ParseError::InvalidEncoding)
|
||||
Err(ParseError::InvalidEncoding(_))
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -471,9 +513,9 @@ mod tests {
|
|||
// receivers we can use are P2PKH and P2SH (which cannot be used together), and
|
||||
// with only one of them we don't have sufficient data for F4Jumble (so we hit a
|
||||
// different error).
|
||||
assert_eq!(
|
||||
assert_matches!(
|
||||
Address::try_from((MAINNET, &encoded[..])),
|
||||
Err(ParseError::InvalidEncoding)
|
||||
Err(ParseError::InvalidEncoding(_))
|
||||
);
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,297 @@
|
|||
pub(crate) struct TestVector {
|
||||
pub(crate) p2pkh_bytes: Option<[u8; 20]>,
|
||||
pub(crate) p2sh_bytes: Option<[u8; 20]>,
|
||||
pub(crate) sapling_raw_addr: Option<[u8; 43]>,
|
||||
pub(crate) orchard_raw_addr: Option<[u8; 43]>,
|
||||
pub(crate) unified_addr: &'static [u8],
|
||||
}
|
||||
|
||||
// From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/unified_address.py
|
||||
pub(crate) const TEST_VECTORS: &[TestVector] = &[
|
||||
TestVector {
|
||||
p2pkh_bytes: None,
|
||||
p2sh_bytes: Some([
|
||||
0x7a, 0x8f, 0x73, 0x9a, 0x2d, 0x9e, 0x94, 0x5b, 0x0c, 0xe1, 0x52, 0xa8, 0x04, 0x9e,
|
||||
0x29, 0x4c, 0x4d, 0x6e, 0x66, 0xb1,
|
||||
]),
|
||||
sapling_raw_addr: None,
|
||||
orchard_raw_addr: Some([
|
||||
0xdc, 0xb1, 0xd2, 0xa3, 0x77, 0x62, 0x14, 0x8d, 0xb4, 0xce, 0xe3, 0xbb, 0xf1, 0x9f,
|
||||
0xb1, 0xec, 0x05, 0x89, 0x18, 0x94, 0xb1, 0x38, 0x01, 0xc6, 0x22, 0xba, 0x6a, 0x90,
|
||||
0xfa, 0xf1, 0x11, 0x9f, 0x82, 0x24, 0xae, 0x39, 0x85, 0xc6, 0xab, 0xd3, 0xb7, 0xbb,
|
||||
0xae,
|
||||
]),
|
||||
unified_addr: &[
|
||||
0x75, 0x31, 0x74, 0x37, 0x79, 0x33, 0x6e, 0x64, 0x76, 0x34, 0x36, 0x74, 0x76, 0x63,
|
||||
0x64, 0x65, 0x37, 0x78, 0x34, 0x36, 0x38, 0x35, 0x61, 0x6a, 0x6d, 0x67, 0x6b, 0x35,
|
||||
0x39, 0x70, 0x64, 0x30, 0x39, 0x32, 0x6c, 0x68, 0x73, 0x34, 0x77, 0x61, 0x6e, 0x77,
|
||||
0x6c, 0x64, 0x68, 0x34, 0x66, 0x6d, 0x37, 0x75, 0x63, 0x6a, 0x72, 0x30, 0x74, 0x34,
|
||||
0x34, 0x68, 0x66, 0x7a, 0x35, 0x6a, 0x63, 0x75, 0x66, 0x7a, 0x75, 0x61, 0x6b, 0x65,
|
||||
0x66, 0x7a, 0x75, 0x71, 0x76, 0x7a, 0x37, 0x6a, 0x30, 0x61, 0x79, 0x74, 0x73, 0x6e,
|
||||
0x66, 0x77, 0x34, 0x70, 0x65, 0x79, 0x64, 0x78, 0x38, 0x75, 0x38, 0x74, 0x6a, 0x73,
|
||||
0x71, 0x34, 0x77, 0x38, 0x75, 0x6b, 0x73, 0x36, 0x72, 0x79, 0x73, 0x63, 0x36, 0x35,
|
||||
0x35, 0x6d, 0x78, 0x6b, 0x6a, 0x36, 0x77, 0x78, 0x78, 0x68, 0x70, 0x67, 0x6b, 0x6e,
|
||||
0x79, 0x73, 0x35, 0x33, 0x65, 0x79, 0x78, 0x70, 0x6b, 0x38, 0x39, 0x78, 0x79, 0x73,
|
||||
0x63,
|
||||
],
|
||||
},
|
||||
TestVector {
|
||||
p2pkh_bytes: Some([
|
||||
0xb3, 0x53, 0x42, 0x01, 0xcf, 0xb1, 0xcd, 0x8d, 0xbf, 0x69, 0xb8, 0x25, 0x0c, 0x18,
|
||||
0xef, 0x41, 0x29, 0x4c, 0xa9, 0x79,
|
||||
]),
|
||||
p2sh_bytes: None,
|
||||
sapling_raw_addr: Some([
|
||||
0x90, 0x2b, 0x65, 0x65, 0xa1, 0xc4, 0x4e, 0x7e, 0x7a, 0x08, 0x05, 0x71, 0xaf, 0x1d,
|
||||
0xd7, 0x74, 0x69, 0x7c, 0xc1, 0x26, 0xf1, 0xfc, 0x04, 0x35, 0xd3, 0xcd, 0xbf, 0x86,
|
||||
0x87, 0x83, 0xe9, 0xfb, 0x46, 0x20, 0xdf, 0x4b, 0xf1, 0x75, 0xcb, 0xf2, 0xc3, 0xe3,
|
||||
0x6f,
|
||||
]),
|
||||
orchard_raw_addr: Some([
|
||||
0x05, 0xf6, 0x12, 0x73, 0xa7, 0x20, 0x12, 0x95, 0x33, 0x2f, 0xee, 0x45, 0x79, 0x47,
|
||||
0x45, 0x34, 0x80, 0x9a, 0x0a, 0xeb, 0x81, 0x7a, 0x2b, 0xc0, 0x59, 0x41, 0x66, 0xad,
|
||||
0x7a, 0x46, 0x20, 0x67, 0x71, 0x25, 0x33, 0xb6, 0xee, 0xc0, 0xfa, 0x2d, 0x1b, 0xe9,
|
||||
0x9f,
|
||||
]),
|
||||
unified_addr: &[
|
||||
0x75, 0x31, 0x66, 0x65, 0x68, 0x6b, 0x65, 0x6a, 0x64, 0x6d, 0x36, 0x30, 0x61, 0x38,
|
||||
0x71, 0x35, 0x35, 0x67, 0x73, 0x65, 0x76, 0x71, 0x6c, 0x78, 0x67, 0x66, 0x32, 0x39,
|
||||
0x6a, 0x38, 0x67, 0x6c, 0x37, 0x73, 0x64, 0x39, 0x34, 0x36, 0x75, 0x6e, 0x6a, 0x73,
|
||||
0x34, 0x6e, 0x6c, 0x34, 0x34, 0x73, 0x63, 0x34, 0x34, 0x30, 0x72, 0x74, 0x65, 0x74,
|
||||
0x35, 0x75, 0x67, 0x71, 0x37, 0x32, 0x64, 0x63, 0x78, 0x39, 0x70, 0x6a, 0x74, 0x68,
|
||||
0x39, 0x6c, 0x32, 0x33, 0x72, 0x70, 0x6a, 0x75, 0x66, 0x75, 0x7a, 0x63, 0x77, 0x68,
|
||||
0x37, 0x35, 0x79, 0x71, 0x65, 0x7a, 0x75, 0x32, 0x35, 0x61, 0x75, 0x32, 0x38, 0x39,
|
||||
0x70, 0x71, 0x72, 0x74, 0x61, 0x6c, 0x71, 0x36, 0x37, 0x77, 0x6e, 0x34, 0x30, 0x66,
|
||||
0x78, 0x71, 0x77, 0x30, 0x6c, 0x6e, 0x37, 0x7a, 0x78, 0x77, 0x7a, 0x39, 0x79, 0x73,
|
||||
0x78, 0x75, 0x75, 0x30, 0x7a, 0x39, 0x33, 0x77, 0x72, 0x67, 0x6e, 0x6d, 0x66, 0x71,
|
||||
0x37, 0x6b, 0x33, 0x66, 0x6e, 0x36, 0x74, 0x7a, 0x63, 0x30, 0x76, 0x37, 0x72, 0x7a,
|
||||
0x39, 0x67, 0x33, 0x70, 0x6a, 0x67, 0x77, 0x75, 0x71, 0x74, 0x6c, 0x6b, 0x7a, 0x78,
|
||||
0x68, 0x73, 0x78, 0x38, 0x39, 0x61, 0x7a, 0x39, 0x65, 0x68, 0x68, 0x33, 0x6c, 0x35,
|
||||
0x6a, 0x35, 0x71, 0x75, 0x75, 0x75, 0x72, 0x77, 0x6e, 0x37, 0x6e, 0x33, 0x74, 0x6a,
|
||||
0x78, 0x6c, 0x61, 0x6e, 0x32, 0x35, 0x72, 0x6e, 0x71, 0x34, 0x67, 0x6a, 0x7a, 0x61,
|
||||
0x38, 0x74, 0x36,
|
||||
],
|
||||
},
|
||||
TestVector {
|
||||
p2pkh_bytes: None,
|
||||
p2sh_bytes: Some([
|
||||
0xe8, 0xc7, 0x20, 0x3d, 0x99, 0x6a, 0xf7, 0xd4, 0x77, 0x08, 0x37, 0x56, 0xd5, 0x9a,
|
||||
0xf8, 0x0d, 0x06, 0xa7, 0x45, 0xf4,
|
||||
]),
|
||||
sapling_raw_addr: None,
|
||||
orchard_raw_addr: Some([
|
||||
0x4e, 0xa7, 0xd6, 0xb3, 0xdf, 0xa3, 0x38, 0x19, 0x2a, 0xf0, 0x6c, 0xbb, 0xf4, 0x7a,
|
||||
0xd4, 0x05, 0x71, 0x5b, 0xc7, 0x83, 0x2b, 0xed, 0xb1, 0x46, 0x62, 0x17, 0xdc, 0x0d,
|
||||
0x93, 0x31, 0x4d, 0xe9, 0xf3, 0xc2, 0x5e, 0xec, 0x89, 0xf9, 0xa2, 0x1b, 0xfe, 0x0e,
|
||||
0x93,
|
||||
]),
|
||||
unified_addr: &[
|
||||
0x75, 0x31, 0x64, 0x6a, 0x68, 0x67, 0x78, 0x77, 0x35, 0x79, 0x74, 0x7a, 0x74, 0x63,
|
||||
0x35, 0x6d, 0x75, 0x32, 0x32, 0x72, 0x34, 0x6d, 0x73, 0x35, 0x67, 0x79, 0x6d, 0x38,
|
||||
0x64, 0x77, 0x68, 0x67, 0x38, 0x34, 0x32, 0x32, 0x66, 0x67, 0x75, 0x78, 0x79, 0x76,
|
||||
0x6c, 0x74, 0x65, 0x78, 0x76, 0x38, 0x78, 0x75, 0x72, 0x67, 0x73, 0x38, 0x63, 0x72,
|
||||
0x30, 0x75, 0x6b, 0x72, 0x64, 0x79, 0x73, 0x37, 0x66, 0x76, 0x68, 0x71, 0x6d, 0x6d,
|
||||
0x61, 0x73, 0x61, 0x66, 0x67, 0x66, 0x65, 0x30, 0x67, 0x74, 0x35, 0x77, 0x6e, 0x30,
|
||||
0x6d, 0x75, 0x6a, 0x6e, 0x63, 0x33, 0x34, 0x67, 0x74, 0x6d, 0x63, 0x77, 0x34, 0x39,
|
||||
0x75, 0x65, 0x64, 0x6b, 0x68, 0x70, 0x7a, 0x79, 0x78, 0x7a, 0x34, 0x39, 0x7a, 0x76,
|
||||
0x78, 0x35, 0x63, 0x39, 0x75, 0x71, 0x30, 0x68, 0x6a, 0x64, 0x35, 0x6e, 0x37, 0x74,
|
||||
0x72, 0x67, 0x73, 0x6e, 0x65, 0x6a, 0x68, 0x6a, 0x71, 0x6d, 0x73, 0x76, 0x72, 0x36,
|
||||
0x63,
|
||||
],
|
||||
},
|
||||
TestVector {
|
||||
p2pkh_bytes: None,
|
||||
p2sh_bytes: None,
|
||||
sapling_raw_addr: Some([
|
||||
0x02, 0xf1, 0x53, 0x6b, 0x62, 0x2c, 0x01, 0x34, 0x67, 0x42, 0xd8, 0xf9, 0x0e, 0x9d,
|
||||
0x4f, 0xf3, 0x91, 0x37, 0xf1, 0xbe, 0xbe, 0x6e, 0x23, 0xad, 0x99, 0x71, 0x77, 0x6b,
|
||||
0x33, 0x72, 0x70, 0x24, 0x94, 0xcc, 0x08, 0x95, 0x1e, 0xef, 0x03, 0x2b, 0x35, 0x35,
|
||||
0x0f,
|
||||
]),
|
||||
orchard_raw_addr: None,
|
||||
unified_addr: &[
|
||||
0x75, 0x31, 0x33, 0x63, 0x36, 0x6d, 0x36, 0x71, 0x6e, 0x65, 0x7a, 0x72, 0x33, 0x79,
|
||||
0x66, 0x75, 0x34, 0x68, 0x75, 0x76, 0x30, 0x35, 0x6e, 0x68, 0x79, 0x61, 0x35, 0x63,
|
||||
0x72, 0x78, 0x6e, 0x35, 0x34, 0x78, 0x61, 0x78, 0x6a, 0x78, 0x37, 0x6d, 0x6b, 0x66,
|
||||
0x74, 0x39, 0x38, 0x61, 0x79, 0x6e, 0x7a, 0x33, 0x6b, 0x68, 0x63, 0x6e, 0x61, 0x76,
|
||||
0x64, 0x79, 0x61, 0x30, 0x6c, 0x74, 0x6a, 0x79, 0x75, 0x65, 0x71, 0x7a, 0x35, 0x77,
|
||||
0x70, 0x6d, 0x30, 0x6d, 0x7a, 0x6a, 0x35, 0x7a, 0x64, 0x6c, 0x34, 0x34, 0x64, 0x32,
|
||||
0x30, 0x76, 0x65, 0x7a, 0x67, 0x68, 0x75, 0x32, 0x72, 0x74, 0x38, 0x61, 0x73, 0x76,
|
||||
0x35, 0x63, 0x6c, 0x61, 0x33, 0x74, 0x64, 0x63,
|
||||
],
|
||||
},
|
||||
TestVector {
|
||||
p2pkh_bytes: None,
|
||||
p2sh_bytes: Some([
|
||||
0x18, 0x3e, 0x31, 0xd4, 0x9f, 0x25, 0xc9, 0xa1, 0x38, 0xf4, 0x9b, 0x1a, 0x53, 0x7e,
|
||||
0xdc, 0xf0, 0x4b, 0xe3, 0x4a, 0x98,
|
||||
]),
|
||||
sapling_raw_addr: Some([
|
||||
0x32, 0x46, 0xb5, 0x9a, 0x5b, 0x49, 0x2d, 0xab, 0x18, 0x55, 0xcc, 0x17, 0x6b, 0xdd,
|
||||
0xfa, 0x28, 0x41, 0x8f, 0x11, 0xf9, 0x7f, 0x7b, 0x36, 0x1c, 0xc3, 0xe8, 0x83, 0x4b,
|
||||
0x2c, 0x30, 0xd2, 0xa1, 0x71, 0x7d, 0xf3, 0x23, 0xef, 0x98, 0xea, 0x7d, 0xe7, 0x1d,
|
||||
0x2e,
|
||||
]),
|
||||
orchard_raw_addr: Some([
|
||||
0xab, 0x6d, 0x26, 0x25, 0x2c, 0x52, 0x15, 0x47, 0x04, 0x9d, 0xe2, 0x08, 0x28, 0x3d,
|
||||
0x96, 0x27, 0x8b, 0xb2, 0x21, 0xa6, 0x87, 0x4c, 0xb5, 0xa8, 0x6a, 0xf1, 0xd3, 0xf8,
|
||||
0xb3, 0xdb, 0x3f, 0xbe, 0xe3, 0xdb, 0xef, 0xed, 0xcb, 0x2c, 0x71, 0xe3, 0xca, 0x1e,
|
||||
0xad,
|
||||
]),
|
||||
unified_addr: &[
|
||||
0x75, 0x31, 0x35, 0x65, 0x32, 0x6e, 0x32, 0x35, 0x36, 0x74, 0x6b, 0x63, 0x68, 0x37,
|
||||
0x39, 0x66, 0x77, 0x79, 0x7a, 0x76, 0x6c, 0x66, 0x33, 0x73, 0x78, 0x66, 0x6c, 0x66,
|
||||
0x72, 0x77, 0x72, 0x66, 0x6d, 0x36, 0x64, 0x33, 0x6d, 0x65, 0x39, 0x30, 0x6e, 0x76,
|
||||
0x39, 0x32, 0x66, 0x6b, 0x65, 0x75, 0x77, 0x6e, 0x65, 0x34, 0x77, 0x73, 0x79, 0x75,
|
||||
0x65, 0x7a, 0x65, 0x6e, 0x71, 0x35, 0x6a, 0x73, 0x68, 0x71, 0x6e, 0x67, 0x30, 0x39,
|
||||
0x6e, 0x77, 0x6c, 0x79, 0x30, 0x35, 0x37, 0x35, 0x71, 0x73, 0x70, 0x37, 0x36, 0x68,
|
||||
0x68, 0x78, 0x78, 0x77, 0x6b, 0x6a, 0x63, 0x73, 0x73, 0x6b, 0x63, 0x65, 0x66, 0x6c,
|
||||
0x38, 0x35, 0x6c, 0x30, 0x74, 0x65, 0x79, 0x33, 0x38, 0x77, 0x32, 0x36, 0x74, 0x6c,
|
||||
0x6c, 0x65, 0x75, 0x78, 0x7a, 0x66, 0x67, 0x6d, 0x38, 0x70, 0x37, 0x32, 0x72, 0x74,
|
||||
0x35, 0x37, 0x30, 0x33, 0x63, 0x72, 0x38, 0x78, 0x75, 0x79, 0x30, 0x75, 0x77, 0x37,
|
||||
0x6c, 0x72, 0x63, 0x74, 0x6e, 0x67, 0x67, 0x39, 0x6b, 0x37, 0x7a, 0x75, 0x38, 0x7a,
|
||||
0x75, 0x66, 0x75, 0x76, 0x39, 0x71, 0x78, 0x63, 0x36, 0x74, 0x79, 0x6a, 0x72, 0x78,
|
||||
0x33, 0x78, 0x33, 0x67, 0x6a, 0x76, 0x79, 0x6b, 0x64, 0x6d, 0x79, 0x61, 0x6d, 0x34,
|
||||
0x79, 0x76, 0x33, 0x79, 0x34, 0x71, 0x37, 0x6a, 0x66, 0x6c, 0x78, 0x30, 0x70, 0x30,
|
||||
0x6d, 0x39, 0x34, 0x70, 0x66, 0x73, 0x77, 0x39, 0x68, 0x7a, 0x6b, 0x37, 0x61, 0x32,
|
||||
0x38, 0x70, 0x79,
|
||||
],
|
||||
},
|
||||
TestVector {
|
||||
p2pkh_bytes: None,
|
||||
p2sh_bytes: None,
|
||||
sapling_raw_addr: Some([
|
||||
0x97, 0x0d, 0xc3, 0x45, 0x0d, 0x34, 0x55, 0x41, 0x41, 0xd3, 0x56, 0xcb, 0x54, 0x80,
|
||||
0x56, 0x27, 0x9c, 0x57, 0x70, 0x8f, 0xa7, 0x3b, 0xd1, 0x6f, 0xfe, 0x9a, 0x2e, 0x24,
|
||||
0xea, 0x69, 0x48, 0x98, 0xa7, 0xb8, 0xaf, 0x1b, 0x0f, 0xf9, 0x25, 0x85, 0xd0, 0x26,
|
||||
0x23,
|
||||
]),
|
||||
orchard_raw_addr: Some([
|
||||
0x04, 0x14, 0xbb, 0x62, 0xb8, 0x61, 0x49, 0xee, 0x73, 0x18, 0x51, 0xf2, 0x7d, 0x53,
|
||||
0x2a, 0xc0, 0x36, 0x11, 0x69, 0xda, 0x46, 0xe6, 0xd5, 0x3d, 0x19, 0xd3, 0xdf, 0xd0,
|
||||
0x7a, 0x5b, 0xae, 0x22, 0x96, 0x99, 0x22, 0xd8, 0xd0, 0xaf, 0x7d, 0xc1, 0xe1, 0x3b,
|
||||
0xae,
|
||||
]),
|
||||
unified_addr: &[
|
||||
0x75, 0x31, 0x6b, 0x61, 0x6c, 0x6b, 0x6d, 0x32, 0x76, 0x71, 0x72, 0x67, 0x71, 0x6d,
|
||||
0x38, 0x6c, 0x6c, 0x71, 0x65, 0x75, 0x68, 0x35, 0x33, 0x72, 0x77, 0x7a, 0x6c, 0x65,
|
||||
0x74, 0x35, 0x67, 0x65, 0x61, 0x34, 0x6d, 0x6b, 0x64, 0x77, 0x39, 0x37, 0x6a, 0x39,
|
||||
0x70, 0x61, 0x33, 0x72, 0x63, 0x65, 0x74, 0x76, 0x7a, 0x76, 0x33, 0x6c, 0x6b, 0x6b,
|
||||
0x33, 0x65, 0x30, 0x75, 0x33, 0x35, 0x34, 0x33, 0x76, 0x70, 0x74, 0x67, 0x74, 0x32,
|
||||
0x6b, 0x30, 0x75, 0x61, 0x66, 0x38, 0x38, 0x36, 0x30, 0x38, 0x66, 0x75, 0x33, 0x75,
|
||||
0x63, 0x65, 0x66, 0x76, 0x77, 0x65, 0x77, 0x79, 0x7a, 0x39, 0x74, 0x71, 0x77, 0x65,
|
||||
0x61, 0x6a, 0x33, 0x77, 0x75, 0x6c, 0x6c, 0x30, 0x70, 0x64, 0x37, 0x30, 0x6d, 0x74,
|
||||
0x6e, 0x68, 0x79, 0x77, 0x65, 0x6b, 0x30, 0x6c, 0x35, 0x76, 0x61, 0x7a, 0x63, 0x61,
|
||||
0x36, 0x65, 0x77, 0x66, 0x34, 0x72, 0x64, 0x6d, 0x77, 0x78, 0x71, 0x38, 0x66, 0x32,
|
||||
0x73, 0x34, 0x70, 0x6d, 0x35, 0x68, 0x71, 0x75, 0x36, 0x6d, 0x65, 0x67, 0x39, 0x7a,
|
||||
0x67, 0x74, 0x67, 0x7a, 0x76, 0x39, 0x38, 0x72, 0x78, 0x7a, 0x68, 0x32, 0x77, 0x78,
|
||||
0x35, 0x76, 0x65, 0x76, 0x79, 0x73, 0x30, 0x34, 0x65, 0x73,
|
||||
],
|
||||
},
|
||||
TestVector {
|
||||
p2pkh_bytes: None,
|
||||
p2sh_bytes: Some([
|
||||
0x09, 0x8b, 0x79, 0x53, 0x5e, 0x79, 0x0f, 0xe5, 0x3e, 0x29, 0xfe, 0xf2, 0xb3, 0x76,
|
||||
0x66, 0x97, 0xac, 0x32, 0xb4, 0xf4,
|
||||
]),
|
||||
sapling_raw_addr: Some([
|
||||
0xa8, 0xa8, 0x79, 0x7c, 0x1b, 0xa6, 0x9f, 0x78, 0x67, 0x2a, 0xff, 0xa6, 0x5b, 0x94,
|
||||
0x39, 0x75, 0x02, 0x69, 0x31, 0xea, 0x62, 0x84, 0x31, 0xf0, 0x99, 0x1e, 0x74, 0x48,
|
||||
0x72, 0xac, 0x9f, 0x36, 0x94, 0x6f, 0x5d, 0xcd, 0x68, 0x51, 0xa0, 0xb5, 0xaf, 0x29,
|
||||
0xcf,
|
||||
]),
|
||||
orchard_raw_addr: Some([
|
||||
0x67, 0x8a, 0xb0, 0x07, 0x9b, 0xea, 0x28, 0xbf, 0x16, 0x5c, 0x1a, 0xb9, 0x76, 0xa2,
|
||||
0xa5, 0x8c, 0x18, 0xa7, 0x81, 0x1c, 0xa2, 0xad, 0x0a, 0xd6, 0x49, 0xe8, 0x76, 0x27,
|
||||
0x3d, 0x04, 0x32, 0x5d, 0xa6, 0xca, 0x53, 0xcd, 0xb8, 0x3c, 0x11, 0x1e, 0x8e, 0x43,
|
||||
0x94,
|
||||
]),
|
||||
unified_addr: &[
|
||||
0x75, 0x31, 0x6d, 0x30, 0x76, 0x7a, 0x6e, 0x37, 0x38, 0x67, 0x68, 0x30, 0x79, 0x6d,
|
||||
0x71, 0x35, 0x6b, 0x71, 0x7a, 0x34, 0x6c, 0x70, 0x64, 0x34, 0x30, 0x39, 0x35, 0x77,
|
||||
0x70, 0x75, 0x65, 0x38, 0x68, 0x6e, 0x68, 0x7a, 0x73, 0x73, 0x35, 0x7a, 0x34, 0x73,
|
||||
0x6c, 0x33, 0x38, 0x73, 0x7a, 0x6e, 0x38, 0x76, 0x77, 0x36, 0x68, 0x39, 0x34, 0x78,
|
||||
0x75, 0x76, 0x63, 0x6a, 0x76, 0x35, 0x61, 0x68, 0x6b, 0x6e, 0x70, 0x6d, 0x6c, 0x72,
|
||||
0x61, 0x36, 0x37, 0x75, 0x65, 0x63, 0x76, 0x6e, 0x6b, 0x6d, 0x73, 0x39, 0x79, 0x66,
|
||||
0x71, 0x78, 0x34, 0x73, 0x37, 0x68, 0x73, 0x6e, 0x73, 0x7a, 0x7a, 0x6d, 0x63, 0x70,
|
||||
0x67, 0x76, 0x78, 0x72, 0x32, 0x30, 0x6c, 0x68, 0x34, 0x35, 0x39, 0x70, 0x73, 0x33,
|
||||
0x75, 0x33, 0x77, 0x66, 0x36, 0x6d, 0x72, 0x7a, 0x77, 0x65, 0x36, 0x78, 0x39, 0x6b,
|
||||
0x64, 0x6a, 0x38, 0x74, 0x70, 0x30, 0x61, 0x36, 0x63, 0x73, 0x65, 0x64, 0x32, 0x65,
|
||||
0x6d, 0x78, 0x70, 0x36, 0x71, 0x37, 0x71, 0x6e, 0x77, 0x61, 0x74, 0x64, 0x32, 0x78,
|
||||
0x6d, 0x34, 0x70, 0x73, 0x6a, 0x68, 0x34, 0x72, 0x34, 0x67, 0x39, 0x70, 0x68, 0x66,
|
||||
0x66, 0x35, 0x34, 0x74, 0x73, 0x75, 0x78, 0x65, 0x35, 0x37, 0x36, 0x38, 0x74, 0x68,
|
||||
0x73, 0x78, 0x73, 0x73, 0x61, 0x76, 0x78, 0x72, 0x66, 0x79, 0x74, 0x70, 0x64, 0x70,
|
||||
0x6d, 0x37, 0x32, 0x6b, 0x6a, 0x73, 0x72, 0x79, 0x70, 0x61, 0x79, 0x7a, 0x77, 0x67,
|
||||
0x71, 0x39, 0x78,
|
||||
],
|
||||
},
|
||||
TestVector {
|
||||
p2pkh_bytes: None,
|
||||
p2sh_bytes: None,
|
||||
sapling_raw_addr: Some([
|
||||
0x35, 0x09, 0xc9, 0xe0, 0x69, 0xe8, 0x9f, 0xe5, 0x01, 0xd9, 0x76, 0x22, 0xc2, 0x83,
|
||||
0xac, 0x98, 0x92, 0x3d, 0xa2, 0xd7, 0xe6, 0xeb, 0x34, 0x6b, 0x4b, 0xaf, 0xa6, 0x78,
|
||||
0x65, 0xe1, 0xe6, 0xda, 0xe7, 0xcf, 0x21, 0x3b, 0x1e, 0xa3, 0x64, 0x8d, 0xc0, 0x9b,
|
||||
0x48,
|
||||
]),
|
||||
orchard_raw_addr: None,
|
||||
unified_addr: &[
|
||||
0x75, 0x31, 0x35, 0x76, 0x76, 0x38, 0x38, 0x34, 0x63, 0x7a, 0x35, 0x64, 0x36, 0x34,
|
||||
0x6e, 0x67, 0x72, 0x32, 0x71, 0x76, 0x34, 0x30, 0x78, 0x35, 0x79, 0x71, 0x71, 0x67,
|
||||
0x7a, 0x36, 0x6a, 0x74, 0x33, 0x68, 0x65, 0x7a, 0x75, 0x39, 0x6d, 0x6b, 0x75, 0x66,
|
||||
0x32, 0x30, 0x64, 0x75, 0x6a, 0x61, 0x66, 0x38, 0x71, 0x76, 0x6b, 0x73, 0x6c, 0x6e,
|
||||
0x78, 0x79, 0x37, 0x38, 0x66, 0x32, 0x64, 0x70, 0x78, 0x79, 0x32, 0x34, 0x70, 0x76,
|
||||
0x76, 0x37, 0x79, 0x76, 0x66, 0x63, 0x7a, 0x6b, 0x6c, 0x30, 0x77, 0x61, 0x65, 0x34,
|
||||
0x35, 0x61, 0x30, 0x70, 0x68, 0x36, 0x64, 0x37, 0x7a, 0x37, 0x64, 0x65, 0x74, 0x33,
|
||||
0x6a, 0x67, 0x34, 0x72, 0x67, 0x67, 0x78, 0x66,
|
||||
],
|
||||
},
|
||||
TestVector {
|
||||
p2pkh_bytes: None,
|
||||
p2sh_bytes: Some([
|
||||
0x30, 0xd0, 0x69, 0x89, 0x6c, 0xff, 0x30, 0xeb, 0x41, 0x4f, 0x72, 0x7b, 0x89, 0xe0,
|
||||
0x01, 0xaf, 0xa2, 0xfb, 0x8d, 0xc3,
|
||||
]),
|
||||
sapling_raw_addr: Some([
|
||||
0x55, 0xbc, 0x46, 0xae, 0xa6, 0xf6, 0x0c, 0x1d, 0x61, 0x91, 0x56, 0x40, 0x02, 0x9b,
|
||||
0x2a, 0xf6, 0x33, 0x4d, 0x7d, 0x27, 0xe1, 0xc4, 0x7a, 0x24, 0x8a, 0xb4, 0x7c, 0x9f,
|
||||
0xbe, 0x5d, 0x2d, 0x7b, 0xb5, 0x81, 0x87, 0x39, 0xf0, 0x62, 0xe3, 0x71, 0x36, 0x65,
|
||||
0x4c,
|
||||
]),
|
||||
orchard_raw_addr: None,
|
||||
unified_addr: &[
|
||||
0x75, 0x31, 0x37, 0x76, 0x6a, 0x73, 0x6b, 0x6c, 0x72, 0x34, 0x75, 0x6a, 0x64, 0x63,
|
||||
0x38, 0x6c, 0x30, 0x7a, 0x68, 0x6b, 0x64, 0x6d, 0x6b, 0x71, 0x71, 0x77, 0x78, 0x34,
|
||||
0x38, 0x33, 0x67, 0x38, 0x61, 0x36, 0x34, 0x32, 0x65, 0x39, 0x37, 0x36, 0x6c, 0x74,
|
||||
0x66, 0x73, 0x30, 0x73, 0x34, 0x6a, 0x65, 0x64, 0x37, 0x61, 0x67, 0x33, 0x76, 0x33,
|
||||
0x61, 0x38, 0x72, 0x6e, 0x67, 0x72, 0x75, 0x36, 0x6e, 0x65, 0x34, 0x38, 0x68, 0x7a,
|
||||
0x72, 0x33, 0x33, 0x6b, 0x6b, 0x7a, 0x70, 0x36, 0x6d, 0x61, 0x67, 0x7a, 0x33, 0x66,
|
||||
0x79, 0x65, 0x6a, 0x77, 0x7a, 0x6a, 0x67, 0x34, 0x33, 0x6a, 0x64, 0x70, 0x65, 0x72,
|
||||
0x74, 0x66, 0x70, 0x78, 0x65, 0x6e, 0x32, 0x66, 0x61, 0x74, 0x7a, 0x35, 0x6b, 0x38,
|
||||
0x30, 0x63, 0x6a, 0x6b, 0x6c, 0x6e, 0x39, 0x71, 0x37, 0x72, 0x39, 0x6d, 0x30, 0x33,
|
||||
0x64, 0x6e, 0x36, 0x67, 0x36, 0x30, 0x63, 0x32, 0x79, 0x6c, 0x33, 0x36, 0x39, 0x34,
|
||||
0x74,
|
||||
],
|
||||
},
|
||||
TestVector {
|
||||
p2pkh_bytes: None,
|
||||
p2sh_bytes: None,
|
||||
sapling_raw_addr: Some([
|
||||
0x5c, 0x26, 0xa8, 0x11, 0x77, 0x29, 0x33, 0x4a, 0x95, 0x7c, 0xa7, 0x94, 0x1d, 0x47,
|
||||
0xb2, 0xce, 0x70, 0x40, 0xe8, 0x44, 0xfa, 0x98, 0x82, 0xc2, 0x5b, 0xfd, 0x2f, 0xcf,
|
||||
0x51, 0xfa, 0x8a, 0xb2, 0x13, 0x76, 0xf5, 0x30, 0x0d, 0x01, 0x23, 0xf5, 0x70, 0x3e,
|
||||
0x9e,
|
||||
]),
|
||||
orchard_raw_addr: None,
|
||||
unified_addr: &[
|
||||
0x75, 0x31, 0x39, 0x76, 0x63, 0x6e, 0x33, 0x72, 0x65, 0x64, 0x70, 0x61, 0x70, 0x68,
|
||||
0x78, 0x34, 0x32, 0x6d, 0x6e, 0x30, 0x73, 0x79, 0x63, 0x32, 0x36, 0x79, 0x38, 0x77,
|
||||
0x39, 0x77, 0x66, 0x67, 0x6c, 0x65, 0x7a, 0x39, 0x61, 0x75, 0x73, 0x6b, 0x61, 0x78,
|
||||
0x72, 0x67, 0x68, 0x6d, 0x78, 0x38, 0x30, 0x64, 0x75, 0x6e, 0x61, 0x33, 0x36, 0x63,
|
||||
0x61, 0x67, 0x63, 0x33, 0x79, 0x73, 0x37, 0x6d, 0x6e, 0x33, 0x6a, 0x37, 0x36, 0x39,
|
||||
0x76, 0x63, 0x67, 0x38, 0x72, 0x75, 0x33, 0x6b, 0x64, 0x6e, 0x61, 0x71, 0x34, 0x70,
|
||||
0x68, 0x34, 0x36, 0x30, 0x34, 0x38, 0x64, 0x68, 0x73, 0x76, 0x6c, 0x35, 0x64, 0x6d,
|
||||
0x64, 0x73, 0x67, 0x78, 0x79, 0x65, 0x38, 0x33,
|
||||
],
|
||||
},
|
||||
];
|
|
@ -1,318 +1,20 @@
|
|||
use std::iter;
|
||||
|
||||
use crate::{
|
||||
unified::{self, Receiver},
|
||||
unified::{self, test_vectors::TEST_VECTORS, Receiver},
|
||||
Network, ToAddress, ZcashAddress,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn unified() {
|
||||
struct TestVector {
|
||||
p2pkh_bytes: Option<[u8; 20]>,
|
||||
p2sh_bytes: Option<[u8; 20]>,
|
||||
sapling_raw_addr: Option<[u8; 43]>,
|
||||
orchard_raw_addr: Option<[u8; 43]>,
|
||||
unified_addr: Vec<u8>,
|
||||
}
|
||||
|
||||
// From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/unified_address.py
|
||||
let test_vectors = vec![
|
||||
TestVector {
|
||||
p2pkh_bytes: None,
|
||||
p2sh_bytes: Some([
|
||||
0x7a, 0x8f, 0x73, 0x9a, 0x2d, 0x9e, 0x94, 0x5b, 0x0c, 0xe1, 0x52, 0xa8, 0x04, 0x9e,
|
||||
0x29, 0x4c, 0x4d, 0x6e, 0x66, 0xb1,
|
||||
]),
|
||||
sapling_raw_addr: None,
|
||||
orchard_raw_addr: Some([
|
||||
0xdc, 0xb1, 0xd2, 0xa3, 0x77, 0x62, 0x14, 0x8d, 0xb4, 0xce, 0xe3, 0xbb, 0xf1, 0x9f,
|
||||
0xb1, 0xec, 0x05, 0x89, 0x18, 0x94, 0xb1, 0x38, 0x01, 0xc6, 0x22, 0xba, 0x6a, 0x90,
|
||||
0xfa, 0xf1, 0x11, 0x9f, 0x82, 0x24, 0xae, 0x39, 0x85, 0xc6, 0xab, 0xd3, 0xb7, 0xbb,
|
||||
0xae,
|
||||
]),
|
||||
unified_addr: vec![
|
||||
0x75, 0x31, 0x65, 0x32, 0x38, 0x66, 0x38, 0x78, 0x7a, 0x6e, 0x65, 0x6d, 0x67, 0x65,
|
||||
0x74, 0x79, 0x78, 0x72, 0x64, 0x7a, 0x6b, 0x66, 0x67, 0x6a, 0x75, 0x67, 0x73, 0x66,
|
||||
0x78, 0x39, 0x64, 0x6b, 0x71, 0x32, 0x74, 0x68, 0x6e, 0x65, 0x7a, 0x65, 0x39, 0x6c,
|
||||
0x33, 0x34, 0x74, 0x70, 0x76, 0x74, 0x70, 0x6d, 0x65, 0x6a, 0x65, 0x67, 0x74, 0x64,
|
||||
0x35, 0x67, 0x68, 0x6b, 0x77, 0x68, 0x67, 0x6a, 0x72, 0x68, 0x73, 0x64, 0x66, 0x64,
|
||||
0x6e, 0x74, 0x33, 0x6b, 0x34, 0x73, 0x66, 0x32, 0x75, 0x79, 0x39, 0x65, 0x61, 0x38,
|
||||
0x63, 0x74, 0x61, 0x75, 0x6d, 0x7a, 0x70, 0x75, 0x64, 0x6c, 0x65, 0x7a, 0x35, 0x66,
|
||||
0x67, 0x75, 0x6c, 0x77, 0x71, 0x6b, 0x70, 0x75, 0x35, 0x66, 0x76, 0x6a, 0x77, 0x79,
|
||||
0x63, 0x74, 0x74, 0x7a, 0x79, 0x64, 0x6c, 0x38, 0x36, 0x64, 0x37, 0x34, 0x34, 0x61,
|
||||
0x34, 0x30, 0x61, 0x71, 0x75, 0x74, 0x7a, 0x68, 0x7a, 0x76, 0x74, 0x79, 0x7a, 0x6e,
|
||||
0x68,
|
||||
],
|
||||
},
|
||||
TestVector {
|
||||
p2pkh_bytes: Some([
|
||||
0xb3, 0x53, 0x42, 0x01, 0xcf, 0xb1, 0xcd, 0x8d, 0xbf, 0x69, 0xb8, 0x25, 0x0c, 0x18,
|
||||
0xef, 0x41, 0x29, 0x4c, 0xa9, 0x79,
|
||||
]),
|
||||
p2sh_bytes: None,
|
||||
sapling_raw_addr: Some([
|
||||
0x90, 0x2b, 0x65, 0x65, 0xa1, 0xc4, 0x4e, 0x7e, 0x7a, 0x08, 0x05, 0x71, 0xaf, 0x1d,
|
||||
0xd7, 0x74, 0x69, 0x7c, 0xc1, 0x26, 0xf1, 0xfc, 0x04, 0x35, 0xd3, 0xcd, 0xbf, 0x86,
|
||||
0x87, 0x83, 0xe9, 0xfb, 0x46, 0x20, 0xdf, 0x4b, 0xf1, 0x75, 0xcb, 0xf2, 0xc3, 0xe3,
|
||||
0x6f,
|
||||
]),
|
||||
orchard_raw_addr: Some([
|
||||
0x05, 0xf6, 0x12, 0x73, 0xa7, 0x20, 0x12, 0x95, 0x33, 0x2f, 0xee, 0x45, 0x79, 0x47,
|
||||
0x45, 0x34, 0x80, 0x9a, 0x0a, 0xeb, 0x81, 0x7a, 0x2b, 0xc0, 0x59, 0x41, 0x66, 0xad,
|
||||
0x7a, 0x46, 0x20, 0x67, 0x71, 0x25, 0x33, 0xb6, 0xee, 0xc0, 0xfa, 0x2d, 0x1b, 0xe9,
|
||||
0x9f,
|
||||
]),
|
||||
unified_addr: vec![
|
||||
0x75, 0x31, 0x33, 0x71, 0x73, 0x32, 0x78, 0x79, 0x6b, 0x66, 0x73, 0x74, 0x64, 0x34,
|
||||
0x33, 0x32, 0x77, 0x70, 0x76, 0x36, 0x63, 0x68, 0x36, 0x73, 0x36, 0x63, 0x6b, 0x68,
|
||||
0x34, 0x73, 0x34, 0x68, 0x33, 0x73, 0x63, 0x72, 0x74, 0x64, 0x35, 0x68, 0x6b, 0x61,
|
||||
0x79, 0x36, 0x72, 0x77, 0x36, 0x6a, 0x6e, 0x36, 0x67, 0x65, 0x6e, 0x37, 0x34, 0x72,
|
||||
0x6d, 0x76, 0x63, 0x61, 0x36, 0x35, 0x77, 0x75, 0x73, 0x67, 0x71, 0x65, 0x36, 0x37,
|
||||
0x71, 0x6d, 0x6b, 0x6b, 0x66, 0x7a, 0x79, 0x68, 0x6c, 0x6b, 0x77, 0x67, 0x38, 0x30,
|
||||
0x71, 0x79, 0x6a, 0x33, 0x72, 0x63, 0x63, 0x61, 0x6e, 0x68, 0x35, 0x66, 0x67, 0x37,
|
||||
0x7a, 0x73, 0x39, 0x30, 0x32, 0x79, 0x32, 0x34, 0x67, 0x6e, 0x32, 0x71, 0x79, 0x66,
|
||||
0x36, 0x70, 0x6b, 0x63, 0x63, 0x63, 0x68, 0x67, 0x30, 0x35, 0x6a, 0x7a, 0x70, 0x33,
|
||||
0x79, 0x72, 0x66, 0x6e, 0x34, 0x70, 0x75, 0x38, 0x61, 0x74, 0x65, 0x38, 0x67, 0x37,
|
||||
0x71, 0x39, 0x72, 0x39, 0x73, 0x74, 0x65, 0x76, 0x78, 0x32, 0x38, 0x34, 0x34, 0x35,
|
||||
0x72, 0x35, 0x77, 0x6e, 0x33, 0x78, 0x33, 0x35, 0x70, 0x66, 0x37, 0x71, 0x71, 0x33,
|
||||
0x32, 0x34, 0x6e, 0x74, 0x68, 0x78, 0x74, 0x7a, 0x63, 0x77, 0x78, 0x65, 0x76, 0x79,
|
||||
0x66, 0x61, 0x34, 0x6c, 0x32, 0x6d, 0x32, 0x6d, 0x32, 0x78, 0x73, 0x37, 0x65, 0x64,
|
||||
0x76, 0x65, 0x70, 0x39, 0x66, 0x74, 0x61, 0x34, 0x76, 0x74, 0x77, 0x76, 0x68, 0x6b,
|
||||
0x61, 0x78, 0x78,
|
||||
],
|
||||
},
|
||||
TestVector {
|
||||
p2pkh_bytes: None,
|
||||
p2sh_bytes: Some([
|
||||
0xe8, 0xc7, 0x20, 0x3d, 0x99, 0x6a, 0xf7, 0xd4, 0x77, 0x08, 0x37, 0x56, 0xd5, 0x9a,
|
||||
0xf8, 0x0d, 0x06, 0xa7, 0x45, 0xf4,
|
||||
]),
|
||||
sapling_raw_addr: None,
|
||||
orchard_raw_addr: Some([
|
||||
0x4e, 0xa7, 0xd6, 0xb3, 0xdf, 0xa3, 0x38, 0x19, 0x2a, 0xf0, 0x6c, 0xbb, 0xf4, 0x7a,
|
||||
0xd4, 0x05, 0x71, 0x5b, 0xc7, 0x83, 0x2b, 0xed, 0xb1, 0x46, 0x62, 0x17, 0xdc, 0x0d,
|
||||
0x93, 0x31, 0x4d, 0xe9, 0xf3, 0xc2, 0x5e, 0xec, 0x89, 0xf9, 0xa2, 0x1b, 0xfe, 0x0e,
|
||||
0x93,
|
||||
]),
|
||||
unified_addr: vec![
|
||||
0x75, 0x31, 0x72, 0x70, 0x77, 0x6b, 0x64, 0x35, 0x78, 0x37, 0x74, 0x65, 0x34, 0x65,
|
||||
0x7a, 0x63, 0x6d, 0x6c, 0x71, 0x61, 0x72, 0x67, 0x6b, 0x66, 0x33, 0x63, 0x72, 0x73,
|
||||
0x70, 0x66, 0x71, 0x6b, 0x68, 0x6d, 0x78, 0x77, 0x66, 0x73, 0x71, 0x70, 0x71, 0x30,
|
||||
0x32, 0x34, 0x6a, 0x61, 0x73, 0x73, 0x32, 0x67, 0x37, 0x34, 0x65, 0x34, 0x72, 0x33,
|
||||
0x36, 0x7a, 0x70, 0x35, 0x30, 0x71, 0x73, 0x73, 0x33, 0x76, 0x68, 0x63, 0x74, 0x37,
|
||||
0x32, 0x73, 0x61, 0x63, 0x68, 0x75, 0x73, 0x30, 0x6b, 0x37, 0x30, 0x35, 0x78, 0x79,
|
||||
0x67, 0x68, 0x75, 0x6c, 0x72, 0x6a, 0x78, 0x63, 0x64, 0x77, 0x77, 0x64, 0x61, 0x71,
|
||||
0x30, 0x71, 0x6a, 0x6e, 0x6e, 0x73, 0x73, 0x66, 0x32, 0x66, 0x76, 0x61, 0x6b, 0x7a,
|
||||
0x7a, 0x38, 0x66, 0x34, 0x36, 0x70, 0x77, 0x38, 0x72, 0x63, 0x61, 0x39, 0x33, 0x36,
|
||||
0x66, 0x65, 0x79, 0x65, 0x66, 0x36, 0x6d, 0x6c, 0x36, 0x65, 0x71, 0x37, 0x77, 0x6c,
|
||||
0x6c,
|
||||
],
|
||||
},
|
||||
TestVector {
|
||||
p2pkh_bytes: None,
|
||||
p2sh_bytes: None,
|
||||
sapling_raw_addr: Some([
|
||||
0x02, 0xf1, 0x53, 0x6b, 0x62, 0x2c, 0x01, 0x34, 0x67, 0x42, 0xd8, 0xf9, 0x0e, 0x9d,
|
||||
0x4f, 0xf3, 0x91, 0x37, 0xf1, 0xbe, 0xbe, 0x6e, 0x23, 0xad, 0x99, 0x71, 0x77, 0x6b,
|
||||
0x33, 0x72, 0x70, 0x24, 0x94, 0xcc, 0x08, 0x95, 0x1e, 0xef, 0x03, 0x2b, 0x35, 0x35,
|
||||
0x0f,
|
||||
]),
|
||||
orchard_raw_addr: None,
|
||||
unified_addr: vec![
|
||||
0x75, 0x31, 0x39, 0x64, 0x68, 0x78, 0x6d, 0x38, 0x38, 0x67, 0x76, 0x63, 0x77, 0x39,
|
||||
0x74, 0x77, 0x74, 0x76, 0x7a, 0x6b, 0x75, 0x37, 0x63, 0x7a, 0x37, 0x6a, 0x75, 0x33,
|
||||
0x72, 0x76, 0x70, 0x75, 0x35, 0x6a, 0x76, 0x68, 0x32, 0x63, 0x71, 0x38, 0x67, 0x6d,
|
||||
0x38, 0x71, 0x64, 0x65, 0x76, 0x6e, 0x6c, 0x34, 0x65, 0x73, 0x65, 0x79, 0x38, 0x33,
|
||||
0x66, 0x7a, 0x72, 0x39, 0x79, 0x6d, 0x66, 0x61, 0x33, 0x67, 0x6a, 0x6d, 0x6d, 0x6b,
|
||||
0x34, 0x72, 0x78, 0x6a, 0x32, 0x79, 0x70, 0x38, 0x38, 0x67, 0x74, 0x78, 0x64, 0x6b,
|
||||
0x71, 0x67, 0x6e, 0x6a, 0x36, 0x6e, 0x6e, 0x71, 0x79, 0x74, 0x66, 0x75, 0x68, 0x30,
|
||||
0x38, 0x75, 0x79, 0x63, 0x35, 0x66, 0x75, 0x72,
|
||||
],
|
||||
},
|
||||
TestVector {
|
||||
p2pkh_bytes: None,
|
||||
p2sh_bytes: Some([
|
||||
0x18, 0x3e, 0x31, 0xd4, 0x9f, 0x25, 0xc9, 0xa1, 0x38, 0xf4, 0x9b, 0x1a, 0x53, 0x7e,
|
||||
0xdc, 0xf0, 0x4b, 0xe3, 0x4a, 0x98,
|
||||
]),
|
||||
sapling_raw_addr: Some([
|
||||
0x32, 0x46, 0xb5, 0x9a, 0x5b, 0x49, 0x2d, 0xab, 0x18, 0x55, 0xcc, 0x17, 0x6b, 0xdd,
|
||||
0xfa, 0x28, 0x41, 0x8f, 0x11, 0xf9, 0x7f, 0x7b, 0x36, 0x1c, 0xc3, 0xe8, 0x83, 0x4b,
|
||||
0x2c, 0x30, 0xd2, 0xa1, 0x71, 0x7d, 0xf3, 0x23, 0xef, 0x98, 0xea, 0x7d, 0xe7, 0x1d,
|
||||
0x2e,
|
||||
]),
|
||||
orchard_raw_addr: Some([
|
||||
0xab, 0x6d, 0x26, 0x25, 0x2c, 0x52, 0x15, 0x47, 0x04, 0x9d, 0xe2, 0x08, 0x28, 0x3d,
|
||||
0x96, 0x27, 0x8b, 0xb2, 0x21, 0xa6, 0x87, 0x4c, 0xb5, 0xa8, 0x6a, 0xf1, 0xd3, 0xf8,
|
||||
0xb3, 0xdb, 0x3f, 0xbe, 0xe3, 0xdb, 0xef, 0xed, 0xcb, 0x2c, 0x71, 0xe3, 0xca, 0x1e,
|
||||
0xad,
|
||||
]),
|
||||
unified_addr: vec![
|
||||
0x75, 0x31, 0x35, 0x63, 0x32, 0x79, 0x72, 0x66, 0x6a, 0x77, 0x74, 0x74, 0x36, 0x36,
|
||||
0x33, 0x6e, 0x71, 0x30, 0x68, 0x70, 0x71, 0x73, 0x68, 0x36, 0x78, 0x74, 0x6a, 0x79,
|
||||
0x32, 0x38, 0x38, 0x7a, 0x74, 0x76, 0x61, 0x63, 0x75, 0x61, 0x6c, 0x37, 0x33, 0x6d,
|
||||
0x66, 0x66, 0x75, 0x72, 0x33, 0x38, 0x33, 0x6d, 0x74, 0x65, 0x70, 0x63, 0x39, 0x68,
|
||||
0x72, 0x78, 0x74, 0x33, 0x74, 0x70, 0x34, 0x65, 0x61, 0x35, 0x68, 0x37, 0x38, 0x30,
|
||||
0x70, 0x67, 0x33, 0x68, 0x6b, 0x35, 0x75, 0x6a, 0x32, 0x67, 0x75, 0x39, 0x37, 0x70,
|
||||
0x32, 0x6c, 0x75, 0x6d, 0x39, 0x71, 0x6a, 0x68, 0x36, 0x32, 0x78, 0x72, 0x61, 0x37,
|
||||
0x63, 0x33, 0x68, 0x79, 0x36, 0x6e, 0x64, 0x71, 0x32, 0x78, 0x77, 0x68, 0x67, 0x37,
|
||||
0x65, 0x71, 0x38, 0x71, 0x37, 0x36, 0x76, 0x66, 0x32, 0x38, 0x63, 0x33, 0x32, 0x64,
|
||||
0x37, 0x76, 0x6d, 0x6c, 0x33, 0x7a, 0x32, 0x39, 0x34, 0x76, 0x74, 0x38, 0x65, 0x63,
|
||||
0x74, 0x63, 0x6c, 0x77, 0x36, 0x72, 0x30, 0x70, 0x32, 0x33, 0x6e, 0x64, 0x70, 0x35,
|
||||
0x78, 0x64, 0x7a, 0x66, 0x65, 0x78, 0x63, 0x39, 0x71, 0x77, 0x30, 0x65, 0x77, 0x75,
|
||||
0x72, 0x79, 0x6e, 0x6a, 0x35, 0x32, 0x35, 0x73, 0x6b, 0x78, 0x37, 0x6d, 0x30, 0x6a,
|
||||
0x75, 0x6b, 0x63, 0x6a, 0x72, 0x65, 0x61, 0x6b, 0x6a, 0x32, 0x61, 0x70, 0x33, 0x32,
|
||||
0x37, 0x6b, 0x6a, 0x71, 0x72, 0x76, 0x75, 0x67, 0x65, 0x64, 0x35, 0x66, 0x79, 0x30,
|
||||
0x73, 0x7a, 0x79,
|
||||
],
|
||||
},
|
||||
TestVector {
|
||||
p2pkh_bytes: None,
|
||||
p2sh_bytes: None,
|
||||
sapling_raw_addr: Some([
|
||||
0x97, 0x0d, 0xc3, 0x45, 0x0d, 0x34, 0x55, 0x41, 0x41, 0xd3, 0x56, 0xcb, 0x54, 0x80,
|
||||
0x56, 0x27, 0x9c, 0x57, 0x70, 0x8f, 0xa7, 0x3b, 0xd1, 0x6f, 0xfe, 0x9a, 0x2e, 0x24,
|
||||
0xea, 0x69, 0x48, 0x98, 0xa7, 0xb8, 0xaf, 0x1b, 0x0f, 0xf9, 0x25, 0x85, 0xd0, 0x26,
|
||||
0x23,
|
||||
]),
|
||||
orchard_raw_addr: Some([
|
||||
0x04, 0x14, 0xbb, 0x62, 0xb8, 0x61, 0x49, 0xee, 0x73, 0x18, 0x51, 0xf2, 0x7d, 0x53,
|
||||
0x2a, 0xc0, 0x36, 0x11, 0x69, 0xda, 0x46, 0xe6, 0xd5, 0x3d, 0x19, 0xd3, 0xdf, 0xd0,
|
||||
0x7a, 0x5b, 0xae, 0x22, 0x96, 0x99, 0x22, 0xd8, 0xd0, 0xaf, 0x7d, 0xc1, 0xe1, 0x3b,
|
||||
0xae,
|
||||
]),
|
||||
unified_addr: vec![
|
||||
0x75, 0x31, 0x7a, 0x64, 0x67, 0x39, 0x7a, 0x37, 0x6c, 0x77, 0x32, 0x71, 0x30, 0x37,
|
||||
0x35, 0x79, 0x77, 0x39, 0x6e, 0x30, 0x6a, 0x37, 0x66, 0x68, 0x38, 0x72, 0x79, 0x75,
|
||||
0x6a, 0x73, 0x72, 0x6a, 0x72, 0x72, 0x37, 0x34, 0x7a, 0x71, 0x78, 0x39, 0x39, 0x33,
|
||||
0x74, 0x63, 0x73, 0x68, 0x74, 0x66, 0x6d, 0x6d, 0x32, 0x71, 0x78, 0x6b, 0x74, 0x76,
|
||||
0x33, 0x72, 0x30, 0x34, 0x38, 0x65, 0x37, 0x74, 0x72, 0x34, 0x71, 0x35, 0x6a, 0x38,
|
||||
0x73, 0x66, 0x65, 0x70, 0x33, 0x67, 0x39, 0x6e, 0x76, 0x38, 0x77, 0x70, 0x78, 0x66,
|
||||
0x39, 0x76, 0x74, 0x72, 0x33, 0x6a, 0x7a, 0x6e, 0x6d, 0x6d, 0x35, 0x36, 0x7a, 0x37,
|
||||
0x75, 0x70, 0x6a, 0x65, 0x30, 0x35, 0x6b, 0x7a, 0x76, 0x6d, 0x75, 0x72, 0x6d, 0x70,
|
||||
0x63, 0x71, 0x70, 0x30, 0x34, 0x63, 0x30, 0x33, 0x37, 0x7a, 0x32, 0x64, 0x68, 0x33,
|
||||
0x35, 0x63, 0x64, 0x38, 0x32, 0x32, 0x35, 0x78, 0x74, 0x33, 0x6b, 0x34, 0x37, 0x6e,
|
||||
0x7a, 0x66, 0x68, 0x32, 0x79, 0x74, 0x73, 0x76, 0x30, 0x37, 0x6d, 0x33, 0x74, 0x38,
|
||||
0x67, 0x64, 0x33, 0x33, 0x70, 0x35, 0x72, 0x32, 0x76, 0x37, 0x6b, 0x66, 0x65, 0x67,
|
||||
0x39, 0x34, 0x35, 0x71, 0x37, 0x6a, 0x63, 0x30, 0x67, 0x68,
|
||||
],
|
||||
},
|
||||
TestVector {
|
||||
p2pkh_bytes: None,
|
||||
p2sh_bytes: Some([
|
||||
0x09, 0x8b, 0x79, 0x53, 0x5e, 0x79, 0x0f, 0xe5, 0x3e, 0x29, 0xfe, 0xf2, 0xb3, 0x76,
|
||||
0x66, 0x97, 0xac, 0x32, 0xb4, 0xf4,
|
||||
]),
|
||||
sapling_raw_addr: Some([
|
||||
0xa8, 0xa8, 0x79, 0x7c, 0x1b, 0xa6, 0x9f, 0x78, 0x67, 0x2a, 0xff, 0xa6, 0x5b, 0x94,
|
||||
0x39, 0x75, 0x02, 0x69, 0x31, 0xea, 0x62, 0x84, 0x31, 0xf0, 0x99, 0x1e, 0x74, 0x48,
|
||||
0x72, 0xac, 0x9f, 0x36, 0x94, 0x6f, 0x5d, 0xcd, 0x68, 0x51, 0xa0, 0xb5, 0xaf, 0x29,
|
||||
0xcf,
|
||||
]),
|
||||
orchard_raw_addr: Some([
|
||||
0x67, 0x8a, 0xb0, 0x07, 0x9b, 0xea, 0x28, 0xbf, 0x16, 0x5c, 0x1a, 0xb9, 0x76, 0xa2,
|
||||
0xa5, 0x8c, 0x18, 0xa7, 0x81, 0x1c, 0xa2, 0xad, 0x0a, 0xd6, 0x49, 0xe8, 0x76, 0x27,
|
||||
0x3d, 0x04, 0x32, 0x5d, 0xa6, 0xca, 0x53, 0xcd, 0xb8, 0x3c, 0x11, 0x1e, 0x8e, 0x43,
|
||||
0x94,
|
||||
]),
|
||||
unified_addr: vec![
|
||||
0x75, 0x31, 0x79, 0x6a, 0x77, 0x33, 0x36, 0x6d, 0x7a, 0x77, 0x7a, 0x34, 0x6a, 0x64,
|
||||
0x38, 0x79, 0x74, 0x6e, 0x72, 0x64, 0x36, 0x67, 0x6b, 0x68, 0x37, 0x61, 0x79, 0x67,
|
||||
0x6d, 0x65, 0x6a, 0x32, 0x72, 0x74, 0x6c, 0x71, 0x67, 0x33, 0x76, 0x6a, 0x39, 0x79,
|
||||
0x65, 0x65, 0x68, 0x66, 0x64, 0x6b, 0x32, 0x33, 0x35, 0x6a, 0x65, 0x73, 0x36, 0x72,
|
||||
0x71, 0x70, 0x66, 0x6a, 0x6c, 0x77, 0x71, 0x67, 0x33, 0x37, 0x76, 0x34, 0x6d, 0x65,
|
||||
0x35, 0x75, 0x67, 0x6a, 0x6c, 0x7a, 0x72, 0x64, 0x6e, 0x68, 0x67, 0x6c, 0x38, 0x38,
|
||||
0x72, 0x72, 0x6c, 0x65, 0x67, 0x38, 0x33, 0x78, 0x38, 0x61, 0x30, 0x71, 0x6d, 0x77,
|
||||
0x79, 0x7a, 0x79, 0x36, 0x39, 0x38, 0x72, 0x38, 0x76, 0x75, 0x63, 0x6e, 0x34, 0x68,
|
||||
0x77, 0x61, 0x67, 0x72, 0x36, 0x71, 0x63, 0x65, 0x7a, 0x73, 0x73, 0x66, 0x36, 0x63,
|
||||
0x68, 0x30, 0x74, 0x37, 0x34, 0x66, 0x63, 0x30, 0x68, 0x76, 0x6e, 0x36, 0x6d, 0x37,
|
||||
0x37, 0x37, 0x68, 0x70, 0x37, 0x35, 0x37, 0x61, 0x76, 0x66, 0x32, 0x63, 0x6b, 0x7a,
|
||||
0x63, 0x33, 0x32, 0x39, 0x35, 0x70, 0x33, 0x32, 0x34, 0x30, 0x71, 0x6c, 0x76, 0x75,
|
||||
0x70, 0x79, 0x64, 0x65, 0x6c, 0x37, 0x33, 0x6c, 0x37, 0x71, 0x63, 0x74, 0x6e, 0x34,
|
||||
0x30, 0x63, 0x79, 0x6b, 0x35, 0x75, 0x36, 0x73, 0x65, 0x73, 0x61, 0x77, 0x72, 0x36,
|
||||
0x7a, 0x6d, 0x6b, 0x74, 0x6c, 0x6a, 0x66, 0x78, 0x68, 0x71, 0x63, 0x63, 0x37, 0x65,
|
||||
0x77, 0x34, 0x68,
|
||||
],
|
||||
},
|
||||
TestVector {
|
||||
p2pkh_bytes: None,
|
||||
p2sh_bytes: None,
|
||||
sapling_raw_addr: Some([
|
||||
0x35, 0x09, 0xc9, 0xe0, 0x69, 0xe8, 0x9f, 0xe5, 0x01, 0xd9, 0x76, 0x22, 0xc2, 0x83,
|
||||
0xac, 0x98, 0x92, 0x3d, 0xa2, 0xd7, 0xe6, 0xeb, 0x34, 0x6b, 0x4b, 0xaf, 0xa6, 0x78,
|
||||
0x65, 0xe1, 0xe6, 0xda, 0xe7, 0xcf, 0x21, 0x3b, 0x1e, 0xa3, 0x64, 0x8d, 0xc0, 0x9b,
|
||||
0x48,
|
||||
]),
|
||||
orchard_raw_addr: None,
|
||||
unified_addr: vec![
|
||||
0x75, 0x31, 0x71, 0x78, 0x6b, 0x79, 0x6d, 0x6b, 0x68, 0x64, 0x7a, 0x63, 0x72, 0x72,
|
||||
0x7a, 0x6c, 0x79, 0x34, 0x66, 0x72, 0x71, 0x75, 0x63, 0x64, 0x6b, 0x66, 0x73, 0x6e,
|
||||
0x6a, 0x37, 0x77, 0x76, 0x77, 0x6c, 0x71, 0x65, 0x75, 0x30, 0x6b, 0x34, 0x66, 0x33,
|
||||
0x74, 0x72, 0x70, 0x6e, 0x65, 0x7a, 0x34, 0x76, 0x77, 0x7a, 0x75, 0x68, 0x6b, 0x64,
|
||||
0x61, 0x6a, 0x6b, 0x35, 0x65, 0x37, 0x36, 0x34, 0x37, 0x34, 0x6d, 0x6a, 0x34, 0x39,
|
||||
0x6b, 0x75, 0x65, 0x39, 0x78, 0x39, 0x68, 0x66, 0x77, 0x65, 0x66, 0x38, 0x6d, 0x34,
|
||||
0x37, 0x73, 0x63, 0x63, 0x38, 0x61, 0x70, 0x39, 0x33, 0x68, 0x6e, 0x67, 0x73, 0x65,
|
||||
0x75, 0x67, 0x33, 0x38, 0x64, 0x70, 0x63, 0x71,
|
||||
],
|
||||
},
|
||||
TestVector {
|
||||
p2pkh_bytes: None,
|
||||
p2sh_bytes: Some([
|
||||
0x30, 0xd0, 0x69, 0x89, 0x6c, 0xff, 0x30, 0xeb, 0x41, 0x4f, 0x72, 0x7b, 0x89, 0xe0,
|
||||
0x01, 0xaf, 0xa2, 0xfb, 0x8d, 0xc3,
|
||||
]),
|
||||
sapling_raw_addr: Some([
|
||||
0x55, 0xbc, 0x46, 0xae, 0xa6, 0xf6, 0x0c, 0x1d, 0x61, 0x91, 0x56, 0x40, 0x02, 0x9b,
|
||||
0x2a, 0xf6, 0x33, 0x4d, 0x7d, 0x27, 0xe1, 0xc4, 0x7a, 0x24, 0x8a, 0xb4, 0x7c, 0x9f,
|
||||
0xbe, 0x5d, 0x2d, 0x7b, 0xb5, 0x81, 0x87, 0x39, 0xf0, 0x62, 0xe3, 0x71, 0x36, 0x65,
|
||||
0x4c,
|
||||
]),
|
||||
orchard_raw_addr: None,
|
||||
unified_addr: vec![
|
||||
0x75, 0x31, 0x64, 0x33, 0x72, 0x6b, 0x71, 0x77, 0x7a, 0x39, 0x6b, 0x37, 0x34, 0x6b,
|
||||
0x74, 0x75, 0x76, 0x6c, 0x74, 0x6e, 0x32, 0x74, 0x6d, 0x74, 0x6a, 0x36, 0x67, 0x6b,
|
||||
0x6c, 0x67, 0x39, 0x33, 0x68, 0x77, 0x73, 0x39, 0x37, 0x79, 0x74, 0x73, 0x33, 0x7a,
|
||||
0x75, 0x36, 0x30, 0x38, 0x76, 0x6b, 0x76, 0x67, 0x33, 0x63, 0x32, 0x79, 0x73, 0x68,
|
||||
0x6d, 0x6d, 0x33, 0x30, 0x71, 0x36, 0x68, 0x38, 0x6b, 0x64, 0x34, 0x72, 0x74, 0x33,
|
||||
0x73, 0x30, 0x76, 0x70, 0x34, 0x75, 0x61, 0x6a, 0x77, 0x66, 0x68, 0x39, 0x61, 0x37,
|
||||
0x35, 0x65, 0x38, 0x61, 0x38, 0x37, 0x30, 0x6e, 0x39, 0x34, 0x6c, 0x6b, 0x70, 0x65,
|
||||
0x78, 0x35, 0x61, 0x73, 0x37, 0x71, 0x6e, 0x77, 0x33, 0x34, 0x36, 0x34, 0x6e, 0x72,
|
||||
0x61, 0x74, 0x75, 0x63, 0x35, 0x6e, 0x35, 0x79, 0x35, 0x75, 0x76, 0x6e, 0x7a, 0x76,
|
||||
0x66, 0x32, 0x6d, 0x34, 0x66, 0x65, 0x6a, 0x68, 0x7a, 0x65, 0x76, 0x68, 0x6e, 0x30,
|
||||
0x6d,
|
||||
],
|
||||
},
|
||||
TestVector {
|
||||
p2pkh_bytes: None,
|
||||
p2sh_bytes: None,
|
||||
sapling_raw_addr: Some([
|
||||
0x5c, 0x26, 0xa8, 0x11, 0x77, 0x29, 0x33, 0x4a, 0x95, 0x7c, 0xa7, 0x94, 0x1d, 0x47,
|
||||
0xb2, 0xce, 0x70, 0x40, 0xe8, 0x44, 0xfa, 0x98, 0x82, 0xc2, 0x5b, 0xfd, 0x2f, 0xcf,
|
||||
0x51, 0xfa, 0x8a, 0xb2, 0x13, 0x76, 0xf5, 0x30, 0x0d, 0x01, 0x23, 0xf5, 0x70, 0x3e,
|
||||
0x9e,
|
||||
]),
|
||||
orchard_raw_addr: None,
|
||||
unified_addr: vec![
|
||||
0x75, 0x31, 0x61, 0x66, 0x61, 0x74, 0x30, 0x64, 0x75, 0x74, 0x61, 0x73, 0x79, 0x66,
|
||||
0x6b, 0x73, 0x61, 0x61, 0x76, 0x6d, 0x34, 0x72, 0x6c, 0x33, 0x61, 0x78, 0x71, 0x6e,
|
||||
0x75, 0x78, 0x6c, 0x77, 0x74, 0x37, 0x36, 0x35, 0x73, 0x39, 0x34, 0x76, 0x39, 0x7a,
|
||||
0x71, 0x6a, 0x74, 0x30, 0x39, 0x7a, 0x79, 0x36, 0x33, 0x64, 0x6c, 0x35, 0x6d, 0x6d,
|
||||
0x79, 0x70, 0x39, 0x78, 0x35, 0x63, 0x6b, 0x76, 0x72, 0x75, 0x6c, 0x6d, 0x64, 0x71,
|
||||
0x34, 0x63, 0x6b, 0x6a, 0x33, 0x72, 0x72, 0x76, 0x37, 0x66, 0x39, 0x6c, 0x37, 0x75,
|
||||
0x6e, 0x78, 0x66, 0x6c, 0x30, 0x64, 0x38, 0x72, 0x36, 0x35, 0x38, 0x32, 0x34, 0x74,
|
||||
0x67, 0x73, 0x67, 0x72, 0x76, 0x67, 0x30, 0x71,
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
for tv in test_vectors {
|
||||
for tv in TEST_VECTORS {
|
||||
// Double-check test vectors match requirements:
|
||||
// - Only one of P2PKH and P2SH.
|
||||
assert!(tv.p2pkh_bytes.is_none() || tv.p2sh_bytes.is_none());
|
||||
// - At least one shielded receiver.
|
||||
assert!(tv.sapling_raw_addr.is_some() || tv.orchard_raw_addr.is_some());
|
||||
|
||||
let addr_string = String::from_utf8(tv.unified_addr).unwrap();
|
||||
let addr_string = String::from_utf8(tv.unified_addr.to_vec()).unwrap();
|
||||
|
||||
let receivers = iter::empty()
|
||||
.chain(tv.orchard_raw_addr.map(Receiver::Orchard))
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
[package]
|
||||
name = "zcash_encoding"
|
||||
description = "Binary encodings used throughout the Zcash ecosystem."
|
||||
version = "0.0.0"
|
||||
authors = [
|
||||
"Jack Grigg <jack@electriccoin.co>",
|
||||
"Kris Nuttycombe <kris@electriccoin.co>",
|
||||
]
|
||||
homepage = "https://github.com/zcash/librustzcash"
|
||||
repository = "https://github.com/zcash/librustzcash"
|
||||
readme = "README.md"
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
byteorder = "1"
|
||||
nonempty = "0.7"
|
||||
|
||||
[dev-dependencies]
|
||||
proptest = "1"
|
||||
|
||||
[lib]
|
||||
bench = false
|
|
@ -0,0 +1,202 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2021 Electric Coin Company
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -0,0 +1,21 @@
|
|||
# zcash_encodings
|
||||
|
||||
This library provides common encoding and decoding operations for stable binary
|
||||
encodings used throughout the Zcash ecosystem.
|
||||
|
||||
## License
|
||||
|
||||
Licensed under either of
|
||||
|
||||
* 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.
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally
|
||||
submitted for inclusion in the work by you, as defined in the Apache-2.0
|
||||
license, shall be dual licensed as above, without any additional terms or
|
||||
conditions.
|
|
@ -1,23 +1,39 @@
|
|||
//! *Zcash binary encodings.*
|
||||
//!
|
||||
//! `zcash_encoding` is a library that provides common encoding and decoding operations
|
||||
//! for stable binary encodings used throughout the Zcash ecosystem.
|
||||
|
||||
// Catch documentation errors caused by code changes.
|
||||
#![deny(broken_intra_doc_links)]
|
||||
#![deny(missing_docs)]
|
||||
#![deny(unsafe_code)]
|
||||
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
use nonempty::NonEmpty;
|
||||
use std::convert::TryFrom;
|
||||
use std::io::{self, Read, Write};
|
||||
|
||||
const MAX_SIZE: usize = 0x02000000;
|
||||
const MAX_SIZE: u64 = 0x02000000;
|
||||
|
||||
pub(crate) struct CompactSize;
|
||||
/// Namespace for functions for compact encoding of integers.
|
||||
///
|
||||
/// This codec requires integers to be in the range `0x0..=0x02000000`, for compatibility
|
||||
/// with Zcash consensus rules.
|
||||
pub struct CompactSize;
|
||||
|
||||
impl CompactSize {
|
||||
pub(crate) fn read<R: Read>(mut reader: R) -> io::Result<usize> {
|
||||
/// Reads an integer encoded in compact form.
|
||||
pub fn read<R: Read>(mut reader: R) -> io::Result<u64> {
|
||||
let flag = reader.read_u8()?;
|
||||
match if flag < 253 {
|
||||
Ok(flag as usize)
|
||||
let result = if flag < 253 {
|
||||
Ok(flag as u64)
|
||||
} else if flag == 253 {
|
||||
match reader.read_u16::<LittleEndian>()? {
|
||||
n if n < 253 => Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"non-canonical CompactSize",
|
||||
)),
|
||||
n => Ok(n as usize),
|
||||
n => Ok(n as u64),
|
||||
}
|
||||
} else if flag == 254 {
|
||||
match reader.read_u32::<LittleEndian>()? {
|
||||
|
@ -25,7 +41,7 @@ impl CompactSize {
|
|||
io::ErrorKind::InvalidInput,
|
||||
"non-canonical CompactSize",
|
||||
)),
|
||||
n => Ok(n as usize),
|
||||
n => Ok(n as u64),
|
||||
}
|
||||
} else {
|
||||
match reader.read_u64::<LittleEndian>()? {
|
||||
|
@ -33,9 +49,11 @@ impl CompactSize {
|
|||
io::ErrorKind::InvalidInput,
|
||||
"non-canonical CompactSize",
|
||||
)),
|
||||
n => Ok(n as usize),
|
||||
n => Ok(n),
|
||||
}
|
||||
}? {
|
||||
}?;
|
||||
|
||||
match result {
|
||||
s if s > MAX_SIZE => Err(io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"CompactSize too large",
|
||||
|
@ -44,7 +62,20 @@ impl CompactSize {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn write<W: Write>(mut writer: W, size: usize) -> io::Result<()> {
|
||||
/// Reads an integer encoded in contact form and performs checked conversion
|
||||
/// to the target type.
|
||||
pub fn read_t<R: Read, T: TryFrom<u64>>(mut reader: R) -> io::Result<T> {
|
||||
let n = Self::read(&mut reader)?;
|
||||
<T>::try_from(n).map_err(|_| {
|
||||
io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"CompactSize value exceeds range of target type.",
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Writes the provided `usize` value to the provided Writer in compact form.
|
||||
pub fn write<W: Write>(mut writer: W, size: usize) -> io::Result<()> {
|
||||
match size {
|
||||
s if s < 253 => writer.write_u8(s as u8),
|
||||
s if s <= 0xFFFF => {
|
||||
|
@ -63,17 +94,26 @@ impl CompactSize {
|
|||
}
|
||||
}
|
||||
|
||||
/// Namespace for functions that perform encoding of vectors.
|
||||
///
|
||||
/// The length of a vector is restricted to at most `0x02000000`, for compatibility with
|
||||
/// the Zcash consensus rules.
|
||||
pub struct Vector;
|
||||
|
||||
impl Vector {
|
||||
/// Reads a vector, assuming the encoding written by [`Vector::write`], using the provided
|
||||
/// function to decode each element of the vector.
|
||||
pub fn read<R: Read, E, F>(mut reader: R, func: F) -> io::Result<Vec<E>>
|
||||
where
|
||||
F: Fn(&mut R) -> io::Result<E>,
|
||||
{
|
||||
let count = CompactSize::read(&mut reader)?;
|
||||
let count: usize = CompactSize::read_t(&mut reader)?;
|
||||
Array::read(reader, count, func)
|
||||
}
|
||||
|
||||
/// Writes a slice of values by writing [`CompactSize`]-encoded integer specifying the length of
|
||||
/// the slice to the stream, followed by the encoding of each element of the slice as performed
|
||||
/// by the provided function.
|
||||
pub fn write<W: Write, E, F>(mut writer: W, vec: &[E], func: F) -> io::Result<()>
|
||||
where
|
||||
F: Fn(&mut W, &E) -> io::Result<()>,
|
||||
|
@ -82,6 +122,8 @@ impl Vector {
|
|||
vec.iter().try_for_each(|e| func(&mut writer, e))
|
||||
}
|
||||
|
||||
/// Writes a NonEmpty container of values to the stream using the same encoding as
|
||||
/// `[Vector::write]`
|
||||
pub fn write_nonempty<W: Write, E, F>(
|
||||
mut writer: W,
|
||||
vec: &NonEmpty<E>,
|
||||
|
@ -95,9 +137,16 @@ impl Vector {
|
|||
}
|
||||
}
|
||||
|
||||
/// Namespace for functions that perform encoding of array contents.
|
||||
///
|
||||
/// This is similar to the [`Vector`] encoding except that no length information is
|
||||
/// written as part of the encoding, so length must be statically known or obtained from
|
||||
/// other parts of the input stream.
|
||||
pub struct Array;
|
||||
|
||||
impl Array {
|
||||
/// Reads a vector, assuming the encoding written by [`Array::write`], using the provided
|
||||
/// function to decode each element of the vector.
|
||||
pub fn read<R: Read, E, F>(mut reader: R, count: usize, func: F) -> io::Result<Vec<E>>
|
||||
where
|
||||
F: Fn(&mut R) -> io::Result<E>,
|
||||
|
@ -105,6 +154,8 @@ impl Array {
|
|||
(0..count).map(|_| func(&mut reader)).collect()
|
||||
}
|
||||
|
||||
/// Writes an iterator full of values to a stream by sequentially
|
||||
/// encoding each element using the provided function.
|
||||
pub fn write<W: Write, E, I: IntoIterator<Item = E>, F>(
|
||||
mut writer: W,
|
||||
vec: I,
|
||||
|
@ -117,9 +168,12 @@ impl Array {
|
|||
}
|
||||
}
|
||||
|
||||
/// Namespace for functions that perform encoding of [`Option`] values.
|
||||
pub struct Optional;
|
||||
|
||||
impl Optional {
|
||||
/// Reads an optional value, assuming the encoding written by [`Optional::write`], using the
|
||||
/// provided function to decode the contained element if present.
|
||||
pub fn read<R: Read, T, F>(mut reader: R, func: F) -> io::Result<Option<T>>
|
||||
where
|
||||
F: Fn(R) -> io::Result<T>,
|
||||
|
@ -134,6 +188,9 @@ impl Optional {
|
|||
}
|
||||
}
|
||||
|
||||
/// Writes an optional value to a stream by writing a flag byte with a value of 0 if no value
|
||||
/// is present, or 1 if there is a value, followed by the encoding of the contents of the
|
||||
/// option as performed by the provided function.
|
||||
pub fn write<W: Write, T, F>(mut writer: W, val: Option<T>, func: F) -> io::Result<()>
|
||||
where
|
||||
F: Fn(W, T) -> io::Result<()>,
|
||||
|
@ -151,34 +208,38 @@ impl Optional {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[test]
|
||||
fn compact_size() {
|
||||
macro_rules! eval {
|
||||
($value:expr, $expected:expr) => {
|
||||
let mut data = vec![];
|
||||
CompactSize::write(&mut data, $value).unwrap();
|
||||
assert_eq!(&data[..], &$expected[..]);
|
||||
match CompactSize::read(&data[..]) {
|
||||
Ok(n) => assert_eq!(n, $value),
|
||||
Err(e) => panic!("Unexpected error: {:?}", e),
|
||||
}
|
||||
};
|
||||
fn eval<T: TryFrom<u64> + TryInto<usize> + Eq + Debug + Copy>(value: T, expected: &[u8])
|
||||
where
|
||||
<T as TryInto<usize>>::Error: Debug,
|
||||
{
|
||||
let mut data = vec![];
|
||||
CompactSize::write(&mut data, value.try_into().unwrap()).unwrap();
|
||||
assert_eq!(&data[..], expected);
|
||||
let result: io::Result<T> = CompactSize::read_t(&data[..]);
|
||||
match result {
|
||||
Ok(n) => assert_eq!(n, value),
|
||||
Err(e) => panic!("Unexpected error: {:?}", e),
|
||||
}
|
||||
}
|
||||
|
||||
eval!(0, [0]);
|
||||
eval!(1, [1]);
|
||||
eval!(252, [252]);
|
||||
eval!(253, [253, 253, 0]);
|
||||
eval!(254, [253, 254, 0]);
|
||||
eval!(255, [253, 255, 0]);
|
||||
eval!(256, [253, 0, 1]);
|
||||
eval!(256, [253, 0, 1]);
|
||||
eval!(65535, [253, 255, 255]);
|
||||
eval!(65536, [254, 0, 0, 1, 0]);
|
||||
eval!(65537, [254, 1, 0, 1, 0]);
|
||||
eval(0, &[0]);
|
||||
eval(1, &[1]);
|
||||
eval(252, &[252]);
|
||||
eval(253, &[253, 253, 0]);
|
||||
eval(254, &[253, 254, 0]);
|
||||
eval(255, &[253, 255, 0]);
|
||||
eval(256, &[253, 0, 1]);
|
||||
eval(256, &[253, 0, 1]);
|
||||
eval(65535, &[253, 255, 255]);
|
||||
eval(65536, &[254, 0, 0, 1, 0]);
|
||||
eval(65537, &[254, 1, 0, 1, 0]);
|
||||
|
||||
eval!(33554432, [254, 0, 0, 0, 2]);
|
||||
eval(33554432, &[254, 0, 0, 0, 2]);
|
||||
|
||||
{
|
||||
let value = 33554433;
|
|
@ -14,15 +14,16 @@ edition = "2018"
|
|||
[dependencies]
|
||||
blake2b_simd = "0.5"
|
||||
byteorder = "1"
|
||||
crypto_api_chachapoly = "0.4"
|
||||
ff = "0.10"
|
||||
group = "0.10"
|
||||
chacha20 = "0.8"
|
||||
chacha20poly1305 = "0.9"
|
||||
ff = "0.11"
|
||||
group = "0.11"
|
||||
rand_core = "0.6"
|
||||
subtle = "2.2.3"
|
||||
|
||||
[dev-dependencies]
|
||||
zcash_primitives = { version = "0.5", path = "../../zcash_primitives" }
|
||||
jubjub = "0.7"
|
||||
jubjub = "0.8"
|
||||
|
||||
[lib]
|
||||
bench = false
|
||||
|
|
|
@ -9,7 +9,8 @@ use crate::{
|
|||
|
||||
/// Trial decryption of a batch of notes with a set of recipients.
|
||||
///
|
||||
/// This is the batched version of [`zcash_note_encryption::try_note_decryption`].
|
||||
/// This is the batched version of [`crate::try_note_decryption`].
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub fn try_note_decryption<D: Domain, Output: ShieldedOutput<D>>(
|
||||
ivks: &[D::IncomingViewingKey],
|
||||
outputs: &[(D, Output)],
|
||||
|
@ -19,7 +20,7 @@ pub fn try_note_decryption<D: Domain, Output: ShieldedOutput<D>>(
|
|||
|
||||
/// Trial decryption of a batch of notes for light clients with a set of recipients.
|
||||
///
|
||||
/// This is the batched version of [`zcash_note_encryption::try_compact_note_decryption`].
|
||||
/// This is the batched version of [`crate::try_compact_note_decryption`].
|
||||
pub fn try_compact_note_decryption<D: Domain, Output: ShieldedOutput<D>>(
|
||||
ivks: &[D::IncomingViewingKey],
|
||||
outputs: &[(D, Output)],
|
||||
|
|
|
@ -3,7 +3,22 @@
|
|||
//! functionality that is shared between the Sapling and Orchard
|
||||
//! protocols.
|
||||
|
||||
use crypto_api_chachapoly::{ChaCha20Ietf, ChachaPolyIetf};
|
||||
// Catch documentation errors caused by code changes.
|
||||
#![deny(broken_intra_doc_links)]
|
||||
#![deny(unsafe_code)]
|
||||
// TODO: #![deny(missing_docs)]
|
||||
|
||||
use std::convert::TryInto;
|
||||
|
||||
use chacha20::{
|
||||
cipher::{NewCipher, StreamCipher, StreamCipherSeek},
|
||||
ChaCha20,
|
||||
};
|
||||
use chacha20poly1305::{
|
||||
aead::{AeadInPlace, NewAead},
|
||||
ChaCha20Poly1305,
|
||||
};
|
||||
|
||||
use rand_core::RngCore;
|
||||
use subtle::{Choice, ConstantTimeEq};
|
||||
|
||||
|
@ -307,12 +322,15 @@ impl<D: Domain> NoteEncryption<D> {
|
|||
let input = D::note_plaintext_bytes(&self.note, &self.to, &self.memo);
|
||||
|
||||
let mut output = [0u8; ENC_CIPHERTEXT_SIZE];
|
||||
assert_eq!(
|
||||
ChachaPolyIetf::aead_cipher()
|
||||
.seal_to(&mut output, &input.0, &[], key.as_ref(), &[0u8; 12])
|
||||
.unwrap(),
|
||||
ENC_CIPHERTEXT_SIZE
|
||||
);
|
||||
output[..NOTE_PLAINTEXT_SIZE].copy_from_slice(&input.0);
|
||||
let tag = ChaCha20Poly1305::new(key.as_ref().into())
|
||||
.encrypt_in_place_detached(
|
||||
[0u8; 12][..].into(),
|
||||
&[],
|
||||
&mut output[..NOTE_PLAINTEXT_SIZE],
|
||||
)
|
||||
.unwrap();
|
||||
output[NOTE_PLAINTEXT_SIZE..].copy_from_slice(&tag);
|
||||
|
||||
output
|
||||
}
|
||||
|
@ -341,12 +359,11 @@ impl<D: Domain> NoteEncryption<D> {
|
|||
};
|
||||
|
||||
let mut output = [0u8; OUT_CIPHERTEXT_SIZE];
|
||||
assert_eq!(
|
||||
ChachaPolyIetf::aead_cipher()
|
||||
.seal_to(&mut output, &input.0, &[], ock.as_ref(), &[0u8; 12])
|
||||
.unwrap(),
|
||||
OUT_CIPHERTEXT_SIZE
|
||||
);
|
||||
output[..OUT_PLAINTEXT_SIZE].copy_from_slice(&input.0);
|
||||
let tag = ChaCha20Poly1305::new(ock.as_ref().into())
|
||||
.encrypt_in_place_detached([0u8; 12][..].into(), &[], &mut output[..OUT_PLAINTEXT_SIZE])
|
||||
.unwrap();
|
||||
output[OUT_PLAINTEXT_SIZE..].copy_from_slice(&tag);
|
||||
|
||||
output
|
||||
}
|
||||
|
@ -381,20 +398,20 @@ fn try_note_decryption_inner<D: Domain, Output: ShieldedOutput<D>>(
|
|||
output: &Output,
|
||||
key: D::SymmetricKey,
|
||||
) -> Option<(D::Note, D::Recipient, D::Memo)> {
|
||||
assert_eq!(output.enc_ciphertext().len(), ENC_CIPHERTEXT_SIZE);
|
||||
let mut plaintext = [0; ENC_CIPHERTEXT_SIZE];
|
||||
assert_eq!(
|
||||
ChachaPolyIetf::aead_cipher()
|
||||
.open_to(
|
||||
&mut plaintext,
|
||||
output.enc_ciphertext(),
|
||||
&[],
|
||||
key.as_ref(),
|
||||
&[0u8; 12]
|
||||
)
|
||||
.ok()?,
|
||||
NOTE_PLAINTEXT_SIZE
|
||||
);
|
||||
let enc_ciphertext = output.enc_ciphertext();
|
||||
assert_eq!(enc_ciphertext.len(), ENC_CIPHERTEXT_SIZE);
|
||||
|
||||
let mut plaintext: [u8; NOTE_PLAINTEXT_SIZE] =
|
||||
enc_ciphertext[..NOTE_PLAINTEXT_SIZE].try_into().unwrap();
|
||||
|
||||
ChaCha20Poly1305::new(key.as_ref().into())
|
||||
.decrypt_in_place_detached(
|
||||
[0u8; 12][..].into(),
|
||||
&[],
|
||||
&mut plaintext,
|
||||
enc_ciphertext[NOTE_PLAINTEXT_SIZE..].into(),
|
||||
)
|
||||
.ok()?;
|
||||
|
||||
let (note, to) = parse_note_plaintext_without_memo_ivk(
|
||||
domain,
|
||||
|
@ -481,7 +498,9 @@ fn try_compact_note_decryption_inner<D: Domain, Output: ShieldedOutput<D>>(
|
|||
// Start from block 1 to skip over Poly1305 keying output
|
||||
let mut plaintext = [0; COMPACT_NOTE_SIZE];
|
||||
plaintext.copy_from_slice(output.enc_ciphertext());
|
||||
ChaCha20Ietf::xor(key.as_ref(), &[0u8; 12], 1, &mut plaintext);
|
||||
let mut keystream = ChaCha20::new(key.as_ref().into(), [0u8; 12][..].into());
|
||||
keystream.seek(64);
|
||||
keystream.apply_keystream(&mut plaintext);
|
||||
|
||||
parse_note_plaintext_without_memo_ivk(
|
||||
domain,
|
||||
|
@ -527,16 +546,21 @@ pub fn try_output_recovery_with_ock<D: Domain, Output: ShieldedOutput<D>>(
|
|||
output: &Output,
|
||||
out_ciphertext: &[u8],
|
||||
) -> Option<(D::Note, D::Recipient, D::Memo)> {
|
||||
assert_eq!(output.enc_ciphertext().len(), ENC_CIPHERTEXT_SIZE);
|
||||
let enc_ciphertext = output.enc_ciphertext();
|
||||
assert_eq!(enc_ciphertext.len(), ENC_CIPHERTEXT_SIZE);
|
||||
assert_eq!(out_ciphertext.len(), OUT_CIPHERTEXT_SIZE);
|
||||
|
||||
let mut op = [0; OUT_PLAINTEXT_SIZE];
|
||||
assert_eq!(
|
||||
ChachaPolyIetf::aead_cipher()
|
||||
.open_to(&mut op, &out_ciphertext, &[], ock.as_ref(), &[0u8; 12])
|
||||
.ok()?,
|
||||
OUT_PLAINTEXT_SIZE
|
||||
);
|
||||
op.copy_from_slice(&out_ciphertext[..OUT_PLAINTEXT_SIZE]);
|
||||
|
||||
ChaCha20Poly1305::new(ock.as_ref().into())
|
||||
.decrypt_in_place_detached(
|
||||
[0u8; 12][..].into(),
|
||||
&[],
|
||||
&mut op,
|
||||
out_ciphertext[OUT_PLAINTEXT_SIZE..].into(),
|
||||
)
|
||||
.ok()?;
|
||||
|
||||
let pk_d = D::extract_pk_d(&op)?;
|
||||
let esk = D::extract_esk(&op)?;
|
||||
|
@ -548,19 +572,17 @@ pub fn try_output_recovery_with_ock<D: Domain, Output: ShieldedOutput<D>>(
|
|||
// be okay.
|
||||
let key = D::kdf(shared_secret, &ephemeral_key);
|
||||
|
||||
let mut plaintext = [0; ENC_CIPHERTEXT_SIZE];
|
||||
assert_eq!(
|
||||
ChachaPolyIetf::aead_cipher()
|
||||
.open_to(
|
||||
&mut plaintext,
|
||||
output.enc_ciphertext(),
|
||||
&[],
|
||||
key.as_ref(),
|
||||
&[0u8; 12]
|
||||
)
|
||||
.ok()?,
|
||||
NOTE_PLAINTEXT_SIZE
|
||||
);
|
||||
let mut plaintext = [0; NOTE_PLAINTEXT_SIZE];
|
||||
plaintext.copy_from_slice(&enc_ciphertext[..NOTE_PLAINTEXT_SIZE]);
|
||||
|
||||
ChaCha20Poly1305::new(key.as_ref().into())
|
||||
.decrypt_in_place_detached(
|
||||
[0u8; 12][..].into(),
|
||||
&[],
|
||||
&mut plaintext,
|
||||
enc_ciphertext[NOTE_PLAINTEXT_SIZE..].into(),
|
||||
)
|
||||
.ok()?;
|
||||
|
||||
let (note, to) =
|
||||
domain.parse_note_plaintext_without_memo_ovk(&pk_d, &esk, &ephemeral_key, &plaintext)?;
|
||||
|
|
|
@ -8,6 +8,7 @@ and this library adheres to Rust's notion of
|
|||
## [Unreleased]
|
||||
### Changed
|
||||
- MSRV is now 1.51.0.
|
||||
- Bumped dependencies to `ff 0.11`, `group 0.11`, `bls12_381 0.6`, `jubjub 0.8`.
|
||||
- `epk: jubjub::ExtendedPoint` has been replaced by
|
||||
`ephemeral_key: zcash_note_encryption::EphemeralKeyBytes` in various places:
|
||||
- `zcash_client_backend::wallet::WalletShieldedOutput`: the `epk` field has
|
||||
|
|
|
@ -14,14 +14,14 @@ edition = "2018"
|
|||
|
||||
[dependencies]
|
||||
bech32 = "0.8"
|
||||
bls12_381 = "0.5"
|
||||
bls12_381 = "0.6"
|
||||
bs58 = { version = "0.4", features = ["check"] }
|
||||
base64 = "0.13"
|
||||
ff = "0.10"
|
||||
group = "0.10"
|
||||
ff = "0.11"
|
||||
group = "0.11"
|
||||
hex = "0.4"
|
||||
hdwallet = { version = "0.3.0", optional = true }
|
||||
jubjub = "0.7"
|
||||
jubjub = "0.8"
|
||||
log = "0.4"
|
||||
nom = "7"
|
||||
percent-encoding = "2.1.0"
|
||||
|
|
|
@ -94,7 +94,7 @@ impl compact_formats::CompactOutput {
|
|||
pub fn cmu(&self) -> Result<bls12_381::Scalar, ()> {
|
||||
let mut repr = [0; 32];
|
||||
repr.as_mut().copy_from_slice(&self.cmu[..]);
|
||||
bls12_381::Scalar::from_repr(repr).ok_or(())
|
||||
Option::from(bls12_381::Scalar::from_repr(repr)).ok_or(())
|
||||
}
|
||||
|
||||
/// Returns the ephemeral public key for this output.
|
||||
|
|
|
@ -8,6 +8,7 @@ and this library adheres to Rust's notion of
|
|||
## [Unreleased]
|
||||
### Changed
|
||||
- MSRV is now 1.51.0.
|
||||
- Bumped dependencies to `ff 0.11`, `group 0.11`, `jubjub 0.8`.
|
||||
- Renamed the following to use lower-case abbreviations (matching Rust
|
||||
naming conventions):
|
||||
- `zcash_client_sqlite::BlockDB` to `BlockDb`
|
||||
|
|
|
@ -15,9 +15,9 @@ edition = "2018"
|
|||
[dependencies]
|
||||
bech32 = "0.8"
|
||||
bs58 = { version = "0.4", features = ["check"] }
|
||||
ff = "0.10"
|
||||
group = "0.10"
|
||||
jubjub = "0.7"
|
||||
ff = "0.11"
|
||||
group = "0.11"
|
||||
jubjub = "0.8"
|
||||
protobuf = "2.20"
|
||||
rand_core = "0.6"
|
||||
rusqlite = { version = "0.24", features = ["bundled", "time"] }
|
||||
|
|
|
@ -37,11 +37,11 @@ fn to_spendable_note(row: &Row) -> Result<SpendableNote, SqliteClientError> {
|
|||
// We store rcm directly in the data DB, regardless of whether the note
|
||||
// used a v1 or v2 note plaintext, so for the purposes of spending let's
|
||||
// pretend this is a pre-ZIP 212 note.
|
||||
let rcm = jubjub::Fr::from_repr(
|
||||
let rcm = Option::from(jubjub::Fr::from_repr(
|
||||
rcm_bytes[..]
|
||||
.try_into()
|
||||
.map_err(|_| SqliteClientError::InvalidNote)?,
|
||||
)
|
||||
))
|
||||
.ok_or(SqliteClientError::InvalidNote)?;
|
||||
Rseed::BeforeZip212(rcm)
|
||||
};
|
||||
|
|
|
@ -13,8 +13,8 @@ blake2b_simd = "0.5"
|
|||
zcash_primitives = { version = "0.5", path = "../zcash_primitives", features = ["zfuture" ] }
|
||||
|
||||
[dev-dependencies]
|
||||
ff = "0.10"
|
||||
jubjub = "0.7"
|
||||
ff = "0.11"
|
||||
jubjub = "0.8"
|
||||
orchard = "0.0"
|
||||
rand_core = "0.6"
|
||||
zcash_proofs = { version = "0.5", path = "../zcash_proofs" }
|
||||
|
|
|
@ -49,9 +49,14 @@ and this library adheres to Rust's notion of
|
|||
type bounded on a newly added `tze::Authorization` trait which
|
||||
is used to enable static reasoning about the state of TZE witness
|
||||
data, as described above.
|
||||
- `zcash_primitives::serialize` has been factored out as a new `zcash_encoding`
|
||||
crate, which can be found in the `components` directory.
|
||||
- `zcash_primitives::transaction::components::Amount` now implements
|
||||
`memuse::DynamicUsage`, to enable `orchard::Bundle<_, Amount>::dynamic_usage`.
|
||||
|
||||
### Changed
|
||||
- MSRV is now 1.51.0.
|
||||
- Bumped dependencies to `ff 0.11`, `group 0.11`, `bls12_381 0.6`, `jubjub 0.8`.
|
||||
- The following modules and helpers have been moved into
|
||||
`zcash_primitives::sapling`:
|
||||
- `zcash_primitives::group_hash`
|
||||
|
|
|
@ -18,24 +18,25 @@ all-features = true
|
|||
[dependencies]
|
||||
aes = "0.7"
|
||||
bitvec = "0.22"
|
||||
bip0039 = { version = "0.8.0", features = ["std", "all-languages"] }
|
||||
bip0039 = { version = "0.9", features = ["std", "all-languages"] }
|
||||
blake2b_simd = "0.5"
|
||||
blake2s_simd = "0.5"
|
||||
bls12_381 = "0.5"
|
||||
bls12_381 = "0.6"
|
||||
byteorder = "1"
|
||||
crypto_api_chachapoly = "0.4"
|
||||
chacha20poly1305 = "0.9"
|
||||
equihash = { version = "0.1", path = "../components/equihash" }
|
||||
ff = "0.10"
|
||||
ff = "0.11"
|
||||
fpe = "0.5"
|
||||
group = "0.10"
|
||||
group = "0.11"
|
||||
hex = "0.4"
|
||||
incrementalmerkletree = "0.1"
|
||||
jubjub = "0.7"
|
||||
jubjub = "0.8"
|
||||
lazy_static = "1"
|
||||
log = "0.4"
|
||||
memuse = "0.2"
|
||||
nonempty = "0.7"
|
||||
orchard = "0.0"
|
||||
pasta_curves = "0.1"
|
||||
pasta_curves = "0.2.1"
|
||||
proptest = { version = "1.0.0", optional = true }
|
||||
rand = "0.8"
|
||||
rand_core = "0.6"
|
||||
|
@ -43,6 +44,7 @@ ripemd160 = { version = "0.9", optional = true }
|
|||
secp256k1 = { version = "0.19", optional = true }
|
||||
sha2 = "0.9"
|
||||
subtle = "2.2.3"
|
||||
zcash_encoding = { version = "0.0", path = "../components/zcash_encoding" }
|
||||
zcash_note_encryption = { version = "0.0", path = "../components/zcash_note_encryption" }
|
||||
|
||||
[dev-dependencies]
|
||||
|
|
|
@ -106,12 +106,7 @@ fn bench_note_decryption(c: &mut Criterion) {
|
|||
let size = 10;
|
||||
let outputs: Vec<_> = iter::repeat(output)
|
||||
.take(size)
|
||||
.map(|output| {
|
||||
(
|
||||
SaplingDomain::for_height(TEST_NETWORK.clone(), height),
|
||||
output,
|
||||
)
|
||||
})
|
||||
.map(|output| (SaplingDomain::for_height(TEST_NETWORK, height), output))
|
||||
.collect();
|
||||
|
||||
let mut group = c.benchmark_group("sapling-batch-note-decryption");
|
||||
|
@ -127,7 +122,7 @@ fn bench_note_decryption(c: &mut Criterion) {
|
|||
|
||||
let compact: Vec<_> = outputs
|
||||
.into_iter()
|
||||
.map(|(domain, output)| (domain, CompactOutputDescription::from(output.clone())))
|
||||
.map(|(domain, output)| (domain, CompactOutputDescription::from(output)))
|
||||
.collect();
|
||||
|
||||
group.bench_function(BenchmarkId::new("compact-valid", size), |b| {
|
||||
|
|
|
@ -5,8 +5,7 @@ use sha2::{Digest, Sha256};
|
|||
use std::fmt;
|
||||
use std::io::{self, Read, Write};
|
||||
use std::ops::Deref;
|
||||
|
||||
use crate::serialize::Vector;
|
||||
use zcash_encoding::Vector;
|
||||
|
||||
pub use equihash;
|
||||
|
||||
|
|
|
@ -240,7 +240,7 @@ impl Parameters for TestNetwork {
|
|||
NetworkUpgrade::Blossom => Some(BlockHeight(584_000)),
|
||||
NetworkUpgrade::Heartwood => Some(BlockHeight(903_800)),
|
||||
NetworkUpgrade::Canopy => Some(BlockHeight(1_028_500)),
|
||||
NetworkUpgrade::Nu5 => None,
|
||||
NetworkUpgrade::Nu5 => Some(BlockHeight(1_599_200)),
|
||||
#[cfg(feature = "zfuture")]
|
||||
NetworkUpgrade::ZFuture => None,
|
||||
}
|
||||
|
@ -458,7 +458,7 @@ impl TryFrom<u32> for BranchId {
|
|||
0x2bb4_0e60 => Ok(BranchId::Blossom),
|
||||
0xf5b9_230b => Ok(BranchId::Heartwood),
|
||||
0xe9ff_75a6 => Ok(BranchId::Canopy),
|
||||
0xf919_a198 => Ok(BranchId::Nu5),
|
||||
0x3751_9621 => Ok(BranchId::Nu5),
|
||||
#[cfg(feature = "zfuture")]
|
||||
0xffff_ffff => Ok(BranchId::ZFuture),
|
||||
_ => Err("Unknown consensus branch ID"),
|
||||
|
@ -475,7 +475,7 @@ impl From<BranchId> for u32 {
|
|||
BranchId::Blossom => 0x2bb4_0e60,
|
||||
BranchId::Heartwood => 0xf5b9_230b,
|
||||
BranchId::Canopy => 0xe9ff_75a6,
|
||||
BranchId::Nu5 => 0xf919_a198,
|
||||
BranchId::Nu5 => 0x3751_9621,
|
||||
#[cfg(feature = "zfuture")]
|
||||
BranchId::ZFuture => 0xffff_ffff,
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ use byteorder::{ReadBytesExt, WriteBytesExt};
|
|||
use std::io::{self, Read, Write};
|
||||
use std::ops::Shl;
|
||||
|
||||
use crate::serialize::Vector;
|
||||
use zcash_encoding::Vector;
|
||||
|
||||
/// Minimal subset of script opcodes.
|
||||
enum OpCode {
|
||||
|
|
|
@ -16,7 +16,6 @@ pub mod legacy;
|
|||
pub mod memo;
|
||||
pub mod merkle_tree;
|
||||
pub mod sapling;
|
||||
pub mod serialize;
|
||||
pub mod transaction;
|
||||
pub mod zip32;
|
||||
pub mod zip339;
|
||||
|
|
|
@ -5,10 +5,9 @@ use incrementalmerkletree::{self, bridgetree, Altitude};
|
|||
use std::collections::VecDeque;
|
||||
use std::convert::TryFrom;
|
||||
use std::io::{self, Read, Write};
|
||||
use zcash_encoding::{Optional, Vector};
|
||||
|
||||
use crate::sapling::SAPLING_COMMITMENT_TREE_DEPTH;
|
||||
use crate::sapling::SAPLING_COMMITMENT_TREE_DEPTH_U8;
|
||||
use crate::serialize::{Optional, Vector};
|
||||
use crate::sapling::{SAPLING_COMMITMENT_TREE_DEPTH, SAPLING_COMMITMENT_TREE_DEPTH_U8};
|
||||
|
||||
pub mod incremental;
|
||||
|
||||
|
|
|
@ -11,10 +11,10 @@ use incrementalmerkletree::{
|
|||
},
|
||||
Hashable, Position,
|
||||
};
|
||||
use orchard::tree::MerkleCrhOrchardOutput;
|
||||
use orchard::tree::MerkleHashOrchard;
|
||||
use zcash_encoding::{Optional, Vector};
|
||||
|
||||
use super::{CommitmentTree, HashSer};
|
||||
use crate::serialize::{Optional, Vector};
|
||||
|
||||
pub const SER_V1: u8 = 1;
|
||||
|
||||
|
@ -26,7 +26,7 @@ pub fn read_frontier_v0<H: Hashable + super::Hashable, R: Read>(
|
|||
Ok(tree.to_frontier())
|
||||
}
|
||||
|
||||
impl HashSer for MerkleCrhOrchardOutput {
|
||||
impl HashSer for MerkleHashOrchard {
|
||||
fn read<R: Read>(mut reader: R) -> io::Result<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
|
|
|
@ -115,7 +115,8 @@ impl HashSer for Node {
|
|||
|
||||
impl From<Node> for bls12_381::Scalar {
|
||||
fn from(node: Node) -> Self {
|
||||
bls12_381::Scalar::from_repr(node.repr).expect("Tree nodes should be in the prime field")
|
||||
// Tree nodes should be in the prime field.
|
||||
bls12_381::Scalar::from_repr(node.repr).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -216,7 +217,7 @@ impl ViewingKey {
|
|||
// Drop the most significant five bits, so it can be interpreted as a scalar.
|
||||
h[31] &= 0b0000_0111;
|
||||
|
||||
SaplingIvk(jubjub::Fr::from_repr(h).expect("should be a valid scalar"))
|
||||
SaplingIvk(jubjub::Fr::from_repr(h).unwrap())
|
||||
}
|
||||
|
||||
pub fn to_payment_address(&self, diversifier: Diversifier) -> Option<PaymentAddress> {
|
||||
|
|
|
@ -72,12 +72,12 @@ impl ExpandedSpendingKey {
|
|||
pub fn read<R: Read>(mut reader: R) -> io::Result<Self> {
|
||||
let mut ask_repr = [0u8; 32];
|
||||
reader.read_exact(ask_repr.as_mut())?;
|
||||
let ask = jubjub::Fr::from_repr(ask_repr)
|
||||
let ask = Option::from(jubjub::Fr::from_repr(ask_repr))
|
||||
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "ask not in field"))?;
|
||||
|
||||
let mut nsk_repr = [0u8; 32];
|
||||
reader.read_exact(nsk_repr.as_mut())?;
|
||||
let nsk = jubjub::Fr::from_repr(nsk_repr)
|
||||
let nsk = Option::from(jubjub::Fr::from_repr(nsk_repr))
|
||||
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "nsk not in field"))?;
|
||||
|
||||
let mut ovk = [0u8; 32];
|
||||
|
|
|
@ -102,7 +102,7 @@ where
|
|||
let r: [u8; 32] = plaintext[20..COMPACT_NOTE_SIZE].try_into().unwrap();
|
||||
|
||||
let rseed = if plaintext[0] == 0x01 {
|
||||
let rcm = jubjub::Fr::from_repr(r)?;
|
||||
let rcm = Option::from(jubjub::Fr::from_repr(r))?;
|
||||
Rseed::BeforeZip212(rcm)
|
||||
} else {
|
||||
Rseed::AfterZip212(r)
|
||||
|
@ -351,6 +351,7 @@ impl<P: consensus::Parameters> Domain for SaplingDomain<P> {
|
|||
.try_into()
|
||||
.expect("slice is the correct length"),
|
||||
)
|
||||
.into()
|
||||
}
|
||||
|
||||
fn extract_memo(&self, plaintext: &[u8]) -> Self::Memo {
|
||||
|
@ -478,7 +479,10 @@ pub fn try_sapling_output_recovery<P: consensus::Parameters>(
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crypto_api_chachapoly::ChachaPolyIetf;
|
||||
use chacha20poly1305::{
|
||||
aead::{AeadInPlace, NewAead},
|
||||
ChaCha20Poly1305,
|
||||
};
|
||||
use ff::{Field, PrimeField};
|
||||
use group::Group;
|
||||
use group::{cofactor::CofactorGroup, GroupEncoding};
|
||||
|
@ -609,13 +613,17 @@ mod tests {
|
|||
) {
|
||||
let ock = prf_ock(&ovk, &cv, &cmu.to_repr(), ephemeral_key);
|
||||
|
||||
let mut op = [0; OUT_CIPHERTEXT_SIZE];
|
||||
assert_eq!(
|
||||
ChachaPolyIetf::aead_cipher()
|
||||
.open_to(&mut op, out_ciphertext, &[], ock.as_ref(), &[0u8; 12])
|
||||
.unwrap(),
|
||||
OUT_PLAINTEXT_SIZE
|
||||
);
|
||||
let mut op = [0; OUT_PLAINTEXT_SIZE];
|
||||
op.copy_from_slice(&out_ciphertext[..OUT_PLAINTEXT_SIZE]);
|
||||
|
||||
ChaCha20Poly1305::new(ock.as_ref().into())
|
||||
.decrypt_in_place_detached(
|
||||
[0u8; 12][..].into(),
|
||||
&[],
|
||||
&mut op,
|
||||
out_ciphertext[OUT_PLAINTEXT_SIZE..].into(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let pk_d = jubjub::SubgroupPoint::from_bytes(&op[0..32].try_into().unwrap()).unwrap();
|
||||
|
||||
|
@ -624,27 +632,26 @@ mod tests {
|
|||
let shared_secret = sapling_ka_agree(&esk, &pk_d.into());
|
||||
let key = kdf_sapling(shared_secret, ephemeral_key);
|
||||
|
||||
let mut plaintext = {
|
||||
let mut buf = [0; ENC_CIPHERTEXT_SIZE];
|
||||
assert_eq!(
|
||||
ChachaPolyIetf::aead_cipher()
|
||||
.open_to(&mut buf, enc_ciphertext, &[], key.as_bytes(), &[0u8; 12])
|
||||
.unwrap(),
|
||||
NOTE_PLAINTEXT_SIZE
|
||||
);
|
||||
let mut pt = [0; NOTE_PLAINTEXT_SIZE];
|
||||
pt.copy_from_slice(&buf[..NOTE_PLAINTEXT_SIZE]);
|
||||
pt
|
||||
};
|
||||
let mut plaintext = [0; NOTE_PLAINTEXT_SIZE];
|
||||
plaintext.copy_from_slice(&enc_ciphertext[..NOTE_PLAINTEXT_SIZE]);
|
||||
|
||||
ChaCha20Poly1305::new(key.as_bytes().into())
|
||||
.decrypt_in_place_detached(
|
||||
[0u8; 12][..].into(),
|
||||
&[],
|
||||
&mut plaintext,
|
||||
enc_ciphertext[NOTE_PLAINTEXT_SIZE..].into(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
modify_plaintext(&mut plaintext);
|
||||
|
||||
assert_eq!(
|
||||
ChachaPolyIetf::aead_cipher()
|
||||
.seal_to(enc_ciphertext, &plaintext, &[], &key.as_bytes(), &[0u8; 12])
|
||||
.unwrap(),
|
||||
ENC_CIPHERTEXT_SIZE
|
||||
);
|
||||
let tag = ChaCha20Poly1305::new(key.as_ref().into())
|
||||
.encrypt_in_place_detached([0u8; 12][..].into(), &[], &mut plaintext)
|
||||
.unwrap();
|
||||
|
||||
enc_ciphertext[..NOTE_PLAINTEXT_SIZE].copy_from_slice(&plaintext);
|
||||
enc_ciphertext[NOTE_PLAINTEXT_SIZE..].copy_from_slice(&tag);
|
||||
}
|
||||
|
||||
fn find_invalid_diversifier() -> Diversifier {
|
||||
|
@ -1349,7 +1356,7 @@ mod tests {
|
|||
let output = OutputDescription {
|
||||
cv,
|
||||
cmu,
|
||||
ephemeral_key: ephemeral_key,
|
||||
ephemeral_key,
|
||||
enc_ciphertext: tv.c_enc,
|
||||
out_ciphertext: tv.c_out,
|
||||
zkproof: [0u8; GROTH_PROOF_SIZE],
|
||||
|
|
|
@ -16,7 +16,7 @@ fn read_scalar<R: Read>(mut reader: R) -> io::Result<jubjub::Fr> {
|
|||
let mut s_repr = [0u8; 32];
|
||||
reader.read_exact(s_repr.as_mut())?;
|
||||
|
||||
jubjub::Fr::from_repr(s_repr)
|
||||
Option::from(jubjub::Fr::from_repr(s_repr))
|
||||
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, "scalar is not in field"))
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,18 @@ pub const DEFAULT_FEE: Amount = Amount(1000);
|
|||
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord)]
|
||||
pub struct Amount(i64);
|
||||
|
||||
impl memuse::DynamicUsage for Amount {
|
||||
#[inline(always)]
|
||||
fn dynamic_usage(&self) -> usize {
|
||||
0
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn dynamic_usage_bounds(&self) -> (usize, Option<usize>) {
|
||||
(0, Some(0))
|
||||
}
|
||||
}
|
||||
|
||||
impl Amount {
|
||||
/// Returns a zero-valued Amount.
|
||||
pub const fn zero() -> Self {
|
||||
|
|
|
@ -11,10 +11,10 @@ use orchard::{
|
|||
value::ValueCommitment,
|
||||
Anchor,
|
||||
};
|
||||
use zcash_encoding::{Array, CompactSize, Vector};
|
||||
|
||||
use super::Amount;
|
||||
use crate::serialize::{Array, CompactSize};
|
||||
use crate::{serialize::Vector, transaction::Transaction};
|
||||
use crate::transaction::Transaction;
|
||||
|
||||
pub const FLAG_SPENDS_ENABLED: u8 = 0b0000_0001;
|
||||
pub const FLAG_OUTPUTS_ENABLED: u8 = 0b0000_0010;
|
||||
|
@ -157,7 +157,7 @@ pub fn read_flags<R: Read>(mut reader: R) -> io::Result<Flags> {
|
|||
pub fn read_anchor<R: Read>(mut reader: R) -> io::Result<Anchor> {
|
||||
let mut bytes = [0u8; 32];
|
||||
reader.read_exact(&mut bytes)?;
|
||||
Anchor::from_bytes(bytes).ok_or_else(|| {
|
||||
Option::from(Anchor::from_bytes(bytes)).ok_or_else(|| {
|
||||
io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
"invalid Orchard anchor".to_owned(),
|
||||
|
|
|
@ -95,7 +95,7 @@ pub fn read_point<R: Read>(mut reader: R, field: &str) -> io::Result<jubjub::Ext
|
|||
pub fn read_base<R: Read>(mut reader: R, field: &str) -> io::Result<bls12_381::Scalar> {
|
||||
let mut f = [0u8; 32];
|
||||
reader.read_exact(&mut f)?;
|
||||
bls12_381::Scalar::from_repr(f).ok_or_else(|| {
|
||||
Option::from(bls12_381::Scalar::from_repr(f)).ok_or_else(|| {
|
||||
io::Error::new(
|
||||
io::ErrorKind::InvalidInput,
|
||||
format!("{} not in field", field),
|
||||
|
|
|
@ -2,18 +2,14 @@
|
|||
#![cfg(feature = "zfuture")]
|
||||
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt::Debug;
|
||||
use std::io::{self, Read, Write};
|
||||
|
||||
use crate::{
|
||||
extensions::transparent as tze,
|
||||
serialize::{CompactSize, Vector},
|
||||
transaction::TxId,
|
||||
};
|
||||
use zcash_encoding::{CompactSize, Vector};
|
||||
|
||||
use super::amount::Amount;
|
||||
use crate::{extensions::transparent as tze, transaction::TxId};
|
||||
|
||||
pub mod builder;
|
||||
|
||||
|
@ -121,15 +117,15 @@ impl TzeIn<<Authorized as Authorization>::Witness> {
|
|||
pub fn read<R: Read>(mut reader: &mut R) -> io::Result<Self> {
|
||||
let prevout = OutPoint::read(&mut reader)?;
|
||||
|
||||
let extension_id = CompactSize::read(&mut reader)?;
|
||||
let mode = CompactSize::read(&mut reader)?;
|
||||
let extension_id = CompactSize::read_t(&mut reader)?;
|
||||
let mode = CompactSize::read_t(&mut reader)?;
|
||||
let payload = Vector::read(&mut reader, |r| r.read_u8())?;
|
||||
|
||||
Ok(TzeIn {
|
||||
prevout,
|
||||
witness: tze::Witness {
|
||||
extension_id: u32::try_from(extension_id).map_err(to_io_error)?,
|
||||
mode: u32::try_from(mode).map_err(to_io_error)?,
|
||||
extension_id,
|
||||
mode,
|
||||
payload: tze::AuthData(payload),
|
||||
},
|
||||
})
|
||||
|
@ -163,15 +159,15 @@ impl TzeOut {
|
|||
}
|
||||
.map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "value out of range"))?;
|
||||
|
||||
let extension_id = CompactSize::read(&mut reader)?;
|
||||
let mode = CompactSize::read(&mut reader)?;
|
||||
let extension_id = CompactSize::read_t(&mut reader)?;
|
||||
let mode = CompactSize::read_t(&mut reader)?;
|
||||
let payload = Vector::read(&mut reader, |r| r.read_u8())?;
|
||||
|
||||
Ok(TzeOut {
|
||||
value,
|
||||
precondition: tze::Precondition {
|
||||
extension_id: u32::try_from(extension_id).map_err(to_io_error)?,
|
||||
mode: u32::try_from(mode).map_err(to_io_error)?,
|
||||
extension_id,
|
||||
mode,
|
||||
payload,
|
||||
},
|
||||
})
|
||||
|
|
|
@ -18,11 +18,11 @@ use std::fmt;
|
|||
use std::fmt::Debug;
|
||||
use std::io::{self, Read, Write};
|
||||
use std::ops::Deref;
|
||||
use zcash_encoding::{Array, CompactSize, Vector};
|
||||
|
||||
use crate::{
|
||||
consensus::{BlockHeight, BranchId},
|
||||
sapling::redjubjub,
|
||||
serialize::{Array, CompactSize, Vector},
|
||||
};
|
||||
|
||||
use self::{
|
||||
|
|
|
@ -19,10 +19,10 @@ use crate::transaction::{
|
|||
use std::convert::TryInto;
|
||||
|
||||
#[cfg(feature = "zfuture")]
|
||||
use crate::{
|
||||
serialize::{CompactSize, Vector},
|
||||
transaction::{components::tze, sighash::TzeInput, TzeDigests},
|
||||
};
|
||||
use zcash_encoding::{CompactSize, Vector};
|
||||
|
||||
#[cfg(feature = "zfuture")]
|
||||
use crate::transaction::{components::tze, sighash::TzeInput, TzeDigests};
|
||||
|
||||
const ZCASH_TRANSPARENT_INPUT_HASH_PERSONALIZATION: &[u8; 16] = b"Zcash___TxInHash";
|
||||
|
||||
|
|
|
@ -5706,7 +5706,7 @@ pub mod zip_0244 {
|
|||
vec![
|
||||
TestVector {
|
||||
tx: vec![
|
||||
0x05, 0x00, 0x00, 0x80, 0x0a, 0x27, 0xa7, 0x26, 0x98, 0xa1, 0x19, 0xf9, 0x7a,
|
||||
0x05, 0x00, 0x00, 0x80, 0x0a, 0x27, 0xa7, 0x26, 0x21, 0x96, 0x51, 0x37, 0x7a,
|
||||
0x8f, 0x73, 0x9a, 0x2d, 0x6f, 0x2c, 0x02, 0x01, 0xe1, 0x52, 0xa8, 0x04, 0x9e,
|
||||
0x29, 0x4c, 0x4d, 0x6e, 0x66, 0xb1, 0x64, 0x93, 0x9d, 0xaf, 0xfa, 0x2e, 0xf6,
|
||||
0xee, 0x69, 0x21, 0x48, 0x1c, 0xdd, 0x86, 0xb3, 0xcc, 0x43, 0x18, 0xd9, 0x61,
|
||||
|
@ -5976,52 +5976,52 @@ pub mod zip_0244 {
|
|||
0x7f, 0x6b, 0x4f, 0xe1, 0x2d, 0xad, 0x9a, 0x17, 0xf5, 0xdb, 0x70, 0x31,
|
||||
],
|
||||
txid: [
|
||||
0xbf, 0x6c, 0x7d, 0x19, 0xf7, 0xc5, 0x65, 0xb1, 0xd4, 0xd9, 0x6d, 0xfb, 0xd0,
|
||||
0x69, 0x8b, 0x3c, 0x87, 0xc7, 0x4a, 0x2a, 0x63, 0xa2, 0x89, 0xd3, 0x00, 0x05,
|
||||
0xda, 0xd6, 0x98, 0x3d, 0x95, 0x44,
|
||||
0x3c, 0x7c, 0xe9, 0x2a, 0x10, 0x59, 0xc0, 0xf6, 0x3f, 0x14, 0x0f, 0x1c, 0xb9,
|
||||
0xac, 0x5e, 0x38, 0x90, 0x0a, 0x68, 0x45, 0x95, 0x63, 0x8f, 0xce, 0xf7, 0x73,
|
||||
0x18, 0x5d, 0xcf, 0x2f, 0x7f, 0x91,
|
||||
],
|
||||
auth_digest: [
|
||||
0x1c, 0xbb, 0xe0, 0xd7, 0x25, 0x4c, 0xa6, 0x52, 0xcd, 0xda, 0xa7, 0xa9, 0xd2,
|
||||
0x91, 0x5a, 0x60, 0x9e, 0x35, 0x73, 0xc0, 0x3d, 0x27, 0x05, 0xe9, 0xad, 0xd4,
|
||||
0xe3, 0x2e, 0xec, 0x0d, 0x76, 0x9e,
|
||||
0x1b, 0x60, 0x46, 0xb6, 0x82, 0xf6, 0x9d, 0xb1, 0x66, 0x65, 0x63, 0x2d, 0x21,
|
||||
0xdc, 0x7f, 0x83, 0x46, 0xb2, 0x82, 0xec, 0x04, 0xb8, 0x40, 0xf2, 0x45, 0x1d,
|
||||
0x09, 0xc0, 0x86, 0x3c, 0xda, 0x6b,
|
||||
],
|
||||
transparent_input: Some(0),
|
||||
script_code: Some(vec![0x65, 0x00, 0x51]),
|
||||
amount: Some(570688904498311),
|
||||
sighash_all: [
|
||||
0xf8, 0xff, 0x73, 0xee, 0x09, 0xf6, 0x4e, 0x10, 0xd8, 0x80, 0x97, 0x39, 0x62,
|
||||
0x10, 0xe8, 0x67, 0xf9, 0x25, 0x4f, 0xf7, 0x40, 0xfd, 0x4f, 0x7d, 0x1f, 0xb7,
|
||||
0xa6, 0x37, 0x60, 0xef, 0x01, 0x64,
|
||||
0x12, 0x5a, 0xab, 0x82, 0x97, 0xf3, 0x0d, 0xe0, 0x38, 0xd1, 0x1a, 0xf8, 0x93,
|
||||
0xbb, 0x77, 0x90, 0x47, 0xec, 0xad, 0x86, 0x7d, 0x03, 0x0a, 0x11, 0x6d, 0x32,
|
||||
0x08, 0x7a, 0x3c, 0xad, 0x1f, 0x2d,
|
||||
],
|
||||
sighash_none: Some([
|
||||
0x89, 0xe6, 0x1b, 0x4b, 0x75, 0x83, 0xea, 0x3d, 0x23, 0xeb, 0x60, 0x2b, 0x82,
|
||||
0x8c, 0x5e, 0xf5, 0x89, 0x32, 0x1b, 0xd6, 0xf6, 0xe3, 0x96, 0x85, 0xa2, 0x44,
|
||||
0xf6, 0x40, 0xd8, 0x75, 0xbe, 0x86,
|
||||
0x08, 0xef, 0x7b, 0x65, 0xb9, 0xd4, 0x15, 0x2b, 0x00, 0x55, 0x24, 0xc9, 0x9e,
|
||||
0x85, 0x0b, 0x0a, 0x7c, 0xe2, 0x6c, 0xc1, 0xbc, 0x00, 0xf7, 0x91, 0x5b, 0xe4,
|
||||
0x7f, 0xdd, 0x4a, 0x0e, 0xe8, 0xe0,
|
||||
]),
|
||||
sighash_single: Some([
|
||||
0x89, 0xe6, 0x1b, 0x4b, 0x75, 0x83, 0xea, 0x3d, 0x23, 0xeb, 0x60, 0x2b, 0x82,
|
||||
0x8c, 0x5e, 0xf5, 0x89, 0x32, 0x1b, 0xd6, 0xf6, 0xe3, 0x96, 0x85, 0xa2, 0x44,
|
||||
0xf6, 0x40, 0xd8, 0x75, 0xbe, 0x86,
|
||||
0x08, 0xef, 0x7b, 0x65, 0xb9, 0xd4, 0x15, 0x2b, 0x00, 0x55, 0x24, 0xc9, 0x9e,
|
||||
0x85, 0x0b, 0x0a, 0x7c, 0xe2, 0x6c, 0xc1, 0xbc, 0x00, 0xf7, 0x91, 0x5b, 0xe4,
|
||||
0x7f, 0xdd, 0x4a, 0x0e, 0xe8, 0xe0,
|
||||
]),
|
||||
sighash_all_anyone: Some([
|
||||
0xf7, 0x59, 0xd3, 0x65, 0x04, 0x80, 0xf4, 0x52, 0xc9, 0x10, 0x3b, 0x71, 0x4f,
|
||||
0x11, 0x38, 0xdd, 0x35, 0x15, 0x53, 0xf0, 0x38, 0x10, 0x8a, 0xba, 0x4d, 0xe2,
|
||||
0xb0, 0x29, 0x33, 0xbe, 0x7b, 0x23,
|
||||
0x0e, 0xba, 0xe2, 0x6e, 0xee, 0xc6, 0x28, 0xbe, 0x1e, 0x76, 0x42, 0xd0, 0xfd,
|
||||
0xb1, 0xdc, 0x13, 0x5b, 0xd1, 0x4f, 0x4f, 0x82, 0xc0, 0x83, 0x4c, 0x02, 0xab,
|
||||
0xd1, 0xdf, 0x5e, 0x3d, 0x77, 0xc6,
|
||||
]),
|
||||
sighash_none_anyone: Some([
|
||||
0xf7, 0x59, 0xd3, 0x65, 0x04, 0x80, 0xf4, 0x52, 0xc9, 0x10, 0x3b, 0x71, 0x4f,
|
||||
0x11, 0x38, 0xdd, 0x35, 0x15, 0x53, 0xf0, 0x38, 0x10, 0x8a, 0xba, 0x4d, 0xe2,
|
||||
0xb0, 0x29, 0x33, 0xbe, 0x7b, 0x23,
|
||||
0x0e, 0xba, 0xe2, 0x6e, 0xee, 0xc6, 0x28, 0xbe, 0x1e, 0x76, 0x42, 0xd0, 0xfd,
|
||||
0xb1, 0xdc, 0x13, 0x5b, 0xd1, 0x4f, 0x4f, 0x82, 0xc0, 0x83, 0x4c, 0x02, 0xab,
|
||||
0xd1, 0xdf, 0x5e, 0x3d, 0x77, 0xc6,
|
||||
]),
|
||||
sighash_single_anyone: Some([
|
||||
0xf7, 0x59, 0xd3, 0x65, 0x04, 0x80, 0xf4, 0x52, 0xc9, 0x10, 0x3b, 0x71, 0x4f,
|
||||
0x11, 0x38, 0xdd, 0x35, 0x15, 0x53, 0xf0, 0x38, 0x10, 0x8a, 0xba, 0x4d, 0xe2,
|
||||
0xb0, 0x29, 0x33, 0xbe, 0x7b, 0x23,
|
||||
0x0e, 0xba, 0xe2, 0x6e, 0xee, 0xc6, 0x28, 0xbe, 0x1e, 0x76, 0x42, 0xd0, 0xfd,
|
||||
0xb1, 0xdc, 0x13, 0x5b, 0xd1, 0x4f, 0x4f, 0x82, 0xc0, 0x83, 0x4c, 0x02, 0xab,
|
||||
0xd1, 0xdf, 0x5e, 0x3d, 0x77, 0xc6,
|
||||
]),
|
||||
},
|
||||
TestVector {
|
||||
tx: vec![
|
||||
0x05, 0x00, 0x00, 0x80, 0x0a, 0x27, 0xa7, 0x26, 0x98, 0xa1, 0x19, 0xf9, 0x1f,
|
||||
0x05, 0x00, 0x00, 0x80, 0x0a, 0x27, 0xa7, 0x26, 0x21, 0x96, 0x51, 0x37, 0x1f,
|
||||
0xc9, 0x98, 0xc3, 0x1f, 0x4d, 0xd2, 0x08, 0x00, 0x01, 0x50, 0x58, 0xe5, 0x75,
|
||||
0x4c, 0x21, 0x04, 0x00, 0x07, 0x53, 0xac, 0x51, 0x53, 0x00, 0x51, 0x52, 0x02,
|
||||
0xf8, 0x9d, 0x32, 0x26, 0xfb, 0x53, 0x29, 0x2b, 0xfb, 0x5d, 0xbb, 0xf7, 0xff,
|
||||
|
@ -6162,22 +6162,22 @@ pub mod zip_0244 {
|
|||
0xfa, 0x0c, 0x00,
|
||||
],
|
||||
txid: [
|
||||
0xcb, 0x18, 0x9c, 0x28, 0x82, 0x9b, 0x17, 0x85, 0x74, 0x7f, 0xa0, 0xb0, 0x4d,
|
||||
0xf8, 0xa5, 0xe4, 0xfc, 0xb7, 0xbf, 0xa7, 0xda, 0x79, 0x29, 0xbf, 0xb7, 0x31,
|
||||
0xac, 0x10, 0xa5, 0x8a, 0xb0, 0x03,
|
||||
0x2f, 0x95, 0xe5, 0xa9, 0x5d, 0x20, 0x9e, 0x0a, 0x27, 0xd1, 0xfe, 0x66, 0x9a,
|
||||
0x46, 0xf4, 0xa6, 0x44, 0xa3, 0x27, 0xd7, 0x9b, 0x84, 0x6e, 0x97, 0x92, 0x64,
|
||||
0x18, 0x6a, 0xde, 0x04, 0x9b, 0xa0,
|
||||
],
|
||||
auth_digest: [
|
||||
0x64, 0xed, 0x51, 0x50, 0x16, 0x96, 0xf1, 0x14, 0x32, 0xb8, 0xa1, 0xe2, 0xe6,
|
||||
0x87, 0xb8, 0x9e, 0x61, 0x25, 0x97, 0xfd, 0x47, 0x49, 0xf9, 0x2c, 0x0f, 0x5f,
|
||||
0x51, 0x71, 0xfc, 0xad, 0x78, 0xbe,
|
||||
0x36, 0x4e, 0xa0, 0xbf, 0x6b, 0xd4, 0xb4, 0xa6, 0x26, 0xdc, 0xcf, 0x0f, 0x96,
|
||||
0xca, 0x1b, 0x0c, 0x3b, 0x4c, 0x46, 0x81, 0x60, 0x24, 0x7b, 0xce, 0x13, 0xf4,
|
||||
0x68, 0x98, 0x84, 0x10, 0x4e, 0xb1,
|
||||
],
|
||||
transparent_input: None,
|
||||
script_code: None,
|
||||
amount: None,
|
||||
sighash_all: [
|
||||
0xcb, 0x18, 0x9c, 0x28, 0x82, 0x9b, 0x17, 0x85, 0x74, 0x7f, 0xa0, 0xb0, 0x4d,
|
||||
0xf8, 0xa5, 0xe4, 0xfc, 0xb7, 0xbf, 0xa7, 0xda, 0x79, 0x29, 0xbf, 0xb7, 0x31,
|
||||
0xac, 0x10, 0xa5, 0x8a, 0xb0, 0x03,
|
||||
0x2f, 0x95, 0xe5, 0xa9, 0x5d, 0x20, 0x9e, 0x0a, 0x27, 0xd1, 0xfe, 0x66, 0x9a,
|
||||
0x46, 0xf4, 0xa6, 0x44, 0xa3, 0x27, 0xd7, 0x9b, 0x84, 0x6e, 0x97, 0x92, 0x64,
|
||||
0x18, 0x6a, 0xde, 0x04, 0x9b, 0xa0,
|
||||
],
|
||||
sighash_none: None,
|
||||
sighash_single: None,
|
||||
|
@ -6187,26 +6187,26 @@ pub mod zip_0244 {
|
|||
},
|
||||
TestVector {
|
||||
tx: vec![
|
||||
0x05, 0x00, 0x00, 0x80, 0x0a, 0x27, 0xa7, 0x26, 0x98, 0xa1, 0x19, 0xf9, 0xc2,
|
||||
0x05, 0x00, 0x00, 0x80, 0x0a, 0x27, 0xa7, 0x26, 0x21, 0x96, 0x51, 0x37, 0xc2,
|
||||
0xeb, 0x51, 0x8f, 0x68, 0x98, 0x4d, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
],
|
||||
txid: [
|
||||
0x7f, 0x4d, 0xd8, 0x79, 0x37, 0x4e, 0x1a, 0x56, 0xa2, 0x32, 0xbb, 0x83, 0xb1,
|
||||
0xcb, 0xf9, 0x57, 0x6a, 0xb7, 0x6b, 0xff, 0xc7, 0x1b, 0xcd, 0x98, 0x5b, 0x62,
|
||||
0xdd, 0xd6, 0x9d, 0x29, 0x97, 0xcd,
|
||||
0xa2, 0x2f, 0x92, 0xf0, 0x43, 0x79, 0x3d, 0x10, 0x9d, 0xb7, 0x43, 0x54, 0xc7,
|
||||
0xd4, 0xe3, 0x28, 0x43, 0xe2, 0x11, 0x95, 0xe7, 0xca, 0xe4, 0xc0, 0x03, 0x0c,
|
||||
0xf8, 0xb4, 0x2c, 0xb6, 0x40, 0xf5,
|
||||
],
|
||||
auth_digest: [
|
||||
0x04, 0xda, 0x78, 0xb6, 0x64, 0x11, 0x1d, 0xe8, 0xe4, 0xfc, 0xfc, 0x14, 0x93,
|
||||
0x3d, 0x79, 0xf6, 0xd9, 0x60, 0xda, 0xd8, 0xf1, 0x08, 0xf1, 0xe0, 0xb4, 0x26,
|
||||
0xcc, 0x20, 0x36, 0x29, 0x22, 0xed,
|
||||
0xd4, 0xfb, 0x0a, 0x17, 0xd1, 0x4a, 0xee, 0x9b, 0x7f, 0x67, 0x05, 0xff, 0x78,
|
||||
0xa1, 0x43, 0xba, 0x07, 0xae, 0x4c, 0x59, 0xb2, 0x3c, 0x84, 0x77, 0xd0, 0xfd,
|
||||
0x72, 0xf5, 0x70, 0x97, 0xb7, 0x38,
|
||||
],
|
||||
transparent_input: None,
|
||||
script_code: None,
|
||||
amount: None,
|
||||
sighash_all: [
|
||||
0x7f, 0x4d, 0xd8, 0x79, 0x37, 0x4e, 0x1a, 0x56, 0xa2, 0x32, 0xbb, 0x83, 0xb1,
|
||||
0xcb, 0xf9, 0x57, 0x6a, 0xb7, 0x6b, 0xff, 0xc7, 0x1b, 0xcd, 0x98, 0x5b, 0x62,
|
||||
0xdd, 0xd6, 0x9d, 0x29, 0x97, 0xcd,
|
||||
0xa2, 0x2f, 0x92, 0xf0, 0x43, 0x79, 0x3d, 0x10, 0x9d, 0xb7, 0x43, 0x54, 0xc7,
|
||||
0xd4, 0xe3, 0x28, 0x43, 0xe2, 0x11, 0x95, 0xe7, 0xca, 0xe4, 0xc0, 0x03, 0x0c,
|
||||
0xf8, 0xb4, 0x2c, 0xb6, 0x40, 0xf5,
|
||||
],
|
||||
sighash_none: None,
|
||||
sighash_single: None,
|
||||
|
@ -6216,27 +6216,27 @@ pub mod zip_0244 {
|
|||
},
|
||||
TestVector {
|
||||
tx: vec![
|
||||
0x05, 0x00, 0x00, 0x80, 0x0a, 0x27, 0xa7, 0x26, 0x98, 0xa1, 0x19, 0xf9, 0x5e,
|
||||
0x05, 0x00, 0x00, 0x80, 0x0a, 0x27, 0xa7, 0x26, 0x21, 0x96, 0x51, 0x37, 0x5e,
|
||||
0x3d, 0xba, 0xf7, 0xae, 0x12, 0x67, 0x0d, 0x00, 0x01, 0x51, 0x6c, 0xf4, 0xad,
|
||||
0xec, 0x75, 0x07, 0x00, 0x03, 0x65, 0x65, 0x00, 0x00, 0x00, 0x00,
|
||||
],
|
||||
txid: [
|
||||
0x8b, 0x26, 0x35, 0x5f, 0x6c, 0xd9, 0x28, 0x8b, 0xf1, 0x15, 0xc3, 0xe6, 0x10,
|
||||
0xa1, 0xe3, 0x4f, 0xd5, 0xf9, 0xc7, 0x9c, 0x9f, 0x78, 0xdc, 0x65, 0x05, 0x1a,
|
||||
0x9a, 0x14, 0xca, 0xc2, 0xb1, 0xbf,
|
||||
0x83, 0xc8, 0xe3, 0x41, 0x04, 0xf1, 0x8b, 0xdb, 0xe8, 0xbb, 0xf6, 0xf0, 0xb9,
|
||||
0xba, 0x53, 0xb5, 0xc6, 0x69, 0x40, 0x61, 0x0c, 0x89, 0x4b, 0xc0, 0xa8, 0x4a,
|
||||
0x16, 0xdc, 0x99, 0x51, 0x24, 0x74,
|
||||
],
|
||||
auth_digest: [
|
||||
0x04, 0xda, 0x78, 0xb6, 0x64, 0x11, 0x1d, 0xe8, 0xe4, 0xfc, 0xfc, 0x14, 0x93,
|
||||
0x3d, 0x79, 0xf6, 0xd9, 0x60, 0xda, 0xd8, 0xf1, 0x08, 0xf1, 0xe0, 0xb4, 0x26,
|
||||
0xcc, 0x20, 0x36, 0x29, 0x22, 0xed,
|
||||
0xd4, 0xfb, 0x0a, 0x17, 0xd1, 0x4a, 0xee, 0x9b, 0x7f, 0x67, 0x05, 0xff, 0x78,
|
||||
0xa1, 0x43, 0xba, 0x07, 0xae, 0x4c, 0x59, 0xb2, 0x3c, 0x84, 0x77, 0xd0, 0xfd,
|
||||
0x72, 0xf5, 0x70, 0x97, 0xb7, 0x38,
|
||||
],
|
||||
transparent_input: None,
|
||||
script_code: None,
|
||||
amount: None,
|
||||
sighash_all: [
|
||||
0x8b, 0x26, 0x35, 0x5f, 0x6c, 0xd9, 0x28, 0x8b, 0xf1, 0x15, 0xc3, 0xe6, 0x10,
|
||||
0xa1, 0xe3, 0x4f, 0xd5, 0xf9, 0xc7, 0x9c, 0x9f, 0x78, 0xdc, 0x65, 0x05, 0x1a,
|
||||
0x9a, 0x14, 0xca, 0xc2, 0xb1, 0xbf,
|
||||
0x83, 0xc8, 0xe3, 0x41, 0x04, 0xf1, 0x8b, 0xdb, 0xe8, 0xbb, 0xf6, 0xf0, 0xb9,
|
||||
0xba, 0x53, 0xb5, 0xc6, 0x69, 0x40, 0x61, 0x0c, 0x89, 0x4b, 0xc0, 0xa8, 0x4a,
|
||||
0x16, 0xdc, 0x99, 0x51, 0x24, 0x74,
|
||||
],
|
||||
sighash_none: None,
|
||||
sighash_single: None,
|
||||
|
@ -6246,7 +6246,7 @@ pub mod zip_0244 {
|
|||
},
|
||||
TestVector {
|
||||
tx: vec![
|
||||
0x05, 0x00, 0x00, 0x80, 0x0a, 0x27, 0xa7, 0x26, 0x98, 0xa1, 0x19, 0xf9, 0xff,
|
||||
0x05, 0x00, 0x00, 0x80, 0x0a, 0x27, 0xa7, 0x26, 0x21, 0x96, 0x51, 0x37, 0xff,
|
||||
0x6a, 0xcc, 0x0f, 0xfc, 0x2e, 0x49, 0x0d, 0x03, 0x14, 0x6b, 0x9d, 0x49, 0xdd,
|
||||
0x8c, 0x78, 0x35, 0xf4, 0x3a, 0x37, 0xdc, 0xa0, 0x78, 0x7e, 0x3e, 0xc9, 0xf6,
|
||||
0x60, 0x52, 0x23, 0xd5, 0xba, 0x7a, 0xe0, 0xab, 0x90, 0x25, 0xb7, 0x3b, 0xc0,
|
||||
|
@ -6264,52 +6264,52 @@ pub mod zip_0244 {
|
|||
0x00,
|
||||
],
|
||||
txid: [
|
||||
0x1e, 0xb3, 0x45, 0x26, 0x36, 0x78, 0x97, 0x7c, 0xce, 0xa4, 0x07, 0x70, 0x85,
|
||||
0xf5, 0x90, 0x93, 0x03, 0xd4, 0x58, 0x0e, 0x72, 0x3a, 0xd3, 0x16, 0x2c, 0x06,
|
||||
0x09, 0x66, 0x48, 0xa2, 0x5b, 0x1e,
|
||||
0x42, 0xf4, 0x80, 0xd6, 0x10, 0xe0, 0xcd, 0xb6, 0xc8, 0x9c, 0xeb, 0xe9, 0x7a,
|
||||
0xf4, 0x0e, 0xd9, 0x8a, 0xb9, 0x0e, 0x43, 0x73, 0xfd, 0xd2, 0x46, 0xb1, 0x01,
|
||||
0xe4, 0x30, 0x21, 0xe7, 0x26, 0x2b,
|
||||
],
|
||||
auth_digest: [
|
||||
0x9e, 0x7c, 0x68, 0x39, 0xb3, 0x1f, 0xb3, 0xe9, 0x12, 0xb6, 0x93, 0xd1, 0x87,
|
||||
0x9f, 0xbb, 0xad, 0xdb, 0xe7, 0xa7, 0x4a, 0x50, 0x8e, 0x7b, 0x6d, 0x1f, 0xe1,
|
||||
0x93, 0x82, 0x68, 0xc0, 0x4a, 0xb3,
|
||||
0x4b, 0x58, 0x88, 0x55, 0x8d, 0x0e, 0xa2, 0x9a, 0x24, 0x27, 0x28, 0x16, 0xb4,
|
||||
0x14, 0x2b, 0x9d, 0xc6, 0x82, 0x56, 0x81, 0xc0, 0xd6, 0xed, 0x99, 0x09, 0x76,
|
||||
0x35, 0x55, 0x40, 0xed, 0x45, 0xf7,
|
||||
],
|
||||
transparent_input: Some(1),
|
||||
script_code: Some(vec![0xac, 0x00, 0x00]),
|
||||
amount: Some(693972628630138),
|
||||
sighash_all: [
|
||||
0x24, 0xa5, 0x08, 0xef, 0xed, 0x90, 0xa6, 0x08, 0x92, 0x13, 0x9b, 0xe9, 0xf8,
|
||||
0x10, 0xfd, 0x82, 0xac, 0x34, 0x0f, 0xb8, 0xb4, 0xfd, 0x23, 0x65, 0x59, 0x6d,
|
||||
0x29, 0xf9, 0x34, 0x17, 0x43, 0xb0,
|
||||
0x2c, 0xac, 0x9b, 0xfd, 0x4a, 0x4a, 0xb0, 0x12, 0x49, 0x21, 0xa2, 0x0c, 0x04,
|
||||
0xf2, 0x53, 0xaf, 0xd3, 0xba, 0x17, 0xec, 0x5c, 0xae, 0xc9, 0xa8, 0x22, 0x35,
|
||||
0x62, 0xb7, 0xa6, 0x41, 0x3a, 0x4f,
|
||||
],
|
||||
sighash_none: Some([
|
||||
0x11, 0x44, 0xde, 0x27, 0x8f, 0x2d, 0x3d, 0x80, 0x0b, 0x95, 0x01, 0x84, 0x2c,
|
||||
0x09, 0xa7, 0x58, 0xa8, 0x11, 0x53, 0x01, 0x62, 0x39, 0x19, 0x59, 0xe9, 0x03,
|
||||
0x71, 0x09, 0x23, 0x9c, 0x4c, 0xb6,
|
||||
0x98, 0x6d, 0xf7, 0x0c, 0xe9, 0x5b, 0x5c, 0x4c, 0x4f, 0x42, 0xb9, 0x66, 0xbb,
|
||||
0x4d, 0x2a, 0x73, 0x1a, 0x78, 0x7d, 0x7f, 0xa8, 0x40, 0xed, 0x5e, 0x7b, 0x02,
|
||||
0x40, 0x93, 0x58, 0x50, 0x70, 0xc3,
|
||||
]),
|
||||
sighash_single: Some([
|
||||
0xc4, 0xc2, 0x61, 0x31, 0x46, 0x7c, 0x1d, 0x4c, 0x4f, 0x8f, 0x38, 0x9f, 0x50,
|
||||
0x85, 0xbe, 0x23, 0xa0, 0x85, 0x36, 0x18, 0x19, 0x45, 0x6d, 0x80, 0xfe, 0x96,
|
||||
0x96, 0x2e, 0xec, 0x3f, 0xc2, 0xb2,
|
||||
0x5c, 0x0d, 0x6b, 0xce, 0x77, 0xa3, 0x94, 0x2c, 0xba, 0x43, 0x28, 0x42, 0xb0,
|
||||
0xdc, 0x51, 0xef, 0x5a, 0x5a, 0xe1, 0x53, 0x9f, 0xf9, 0x9c, 0xf1, 0x55, 0xa5,
|
||||
0x9f, 0x45, 0xaf, 0x2a, 0xe3, 0x0c,
|
||||
]),
|
||||
sighash_all_anyone: Some([
|
||||
0xe1, 0x3b, 0x4b, 0xfb, 0xb2, 0x4e, 0x2b, 0xd7, 0xd9, 0xac, 0xb0, 0x3d, 0x0c,
|
||||
0xc0, 0xdc, 0x46, 0x35, 0xd8, 0xf7, 0x9e, 0xe9, 0x26, 0xcd, 0xf7, 0x17, 0xc5,
|
||||
0x5f, 0xef, 0x33, 0x75, 0x61, 0x86,
|
||||
0xd7, 0x52, 0x77, 0xd4, 0x24, 0x0e, 0x70, 0xab, 0x54, 0x98, 0xbf, 0xa7, 0xcf,
|
||||
0x99, 0x89, 0x1c, 0x46, 0x16, 0x57, 0xce, 0xa0, 0xf6, 0x28, 0xf0, 0x53, 0x6e,
|
||||
0x42, 0x87, 0x6d, 0xde, 0x6e, 0x52,
|
||||
]),
|
||||
sighash_none_anyone: Some([
|
||||
0x21, 0xae, 0xbe, 0xc0, 0xdb, 0x41, 0xad, 0x64, 0x04, 0x18, 0x32, 0x4b, 0xcf,
|
||||
0xfc, 0x15, 0xaa, 0x0a, 0x63, 0x5c, 0xf8, 0xf7, 0xf6, 0xbe, 0x35, 0xc5, 0x7e,
|
||||
0x02, 0x06, 0xd7, 0x67, 0x87, 0x6a,
|
||||
0xe6, 0x9b, 0xf5, 0x8c, 0x28, 0x86, 0xa8, 0xa4, 0xd8, 0x57, 0x53, 0x24, 0xce,
|
||||
0x8e, 0xe5, 0xd9, 0x19, 0x80, 0x83, 0xc8, 0xde, 0x79, 0x9e, 0x3b, 0x6c, 0x2b,
|
||||
0x58, 0xa4, 0x74, 0xa6, 0x9b, 0x28,
|
||||
]),
|
||||
sighash_single_anyone: Some([
|
||||
0xb6, 0x0f, 0xcb, 0xf6, 0xd5, 0xf9, 0xd9, 0x2d, 0x38, 0x86, 0xe1, 0xe8, 0x87,
|
||||
0x0d, 0x48, 0x08, 0x7c, 0x21, 0x51, 0x01, 0x94, 0xaa, 0xc6, 0xad, 0xf8, 0xf3,
|
||||
0x55, 0x29, 0x90, 0x61, 0xf6, 0x20,
|
||||
0x9e, 0x53, 0x5b, 0x3d, 0x36, 0x52, 0xae, 0xf5, 0xe9, 0x63, 0xf2, 0xff, 0xec,
|
||||
0x33, 0x27, 0x8d, 0x92, 0xee, 0xed, 0xd0, 0x0d, 0xaf, 0x9c, 0x6c, 0x2b, 0x42,
|
||||
0xb0, 0xdc, 0x41, 0x84, 0x98, 0x5d,
|
||||
]),
|
||||
},
|
||||
TestVector {
|
||||
tx: vec![
|
||||
0x05, 0x00, 0x00, 0x80, 0x0a, 0x27, 0xa7, 0x26, 0x98, 0xa1, 0x19, 0xf9, 0xde,
|
||||
0x05, 0x00, 0x00, 0x80, 0x0a, 0x27, 0xa7, 0x26, 0x21, 0x96, 0x51, 0x37, 0xde,
|
||||
0xdc, 0x5e, 0x5f, 0x07, 0x56, 0xfb, 0x19, 0x00, 0x01, 0x33, 0xa4, 0x90, 0x76,
|
||||
0x8c, 0x16, 0x00, 0x00, 0x08, 0x51, 0x53, 0x53, 0x51, 0x51, 0x65, 0x63, 0x00,
|
||||
0x00, 0x01, 0xda, 0xb9, 0x57, 0x81, 0x57, 0xeb, 0xf9, 0xcd, 0x81, 0x13, 0x07,
|
||||
|
@ -6542,22 +6542,22 @@ pub mod zip_0244 {
|
|||
0x52, 0xaa, 0xf0, 0x16,
|
||||
],
|
||||
txid: [
|
||||
0xad, 0x80, 0x74, 0x56, 0xa6, 0xc0, 0x16, 0x51, 0xf0, 0x80, 0xd1, 0xdd, 0x71,
|
||||
0x87, 0x1f, 0x14, 0x12, 0xe3, 0x8f, 0x89, 0x13, 0x07, 0x52, 0x80, 0xcd, 0x2b,
|
||||
0x38, 0x02, 0xf5, 0xb2, 0x70, 0x4e,
|
||||
0x44, 0x1f, 0xad, 0xb2, 0x5a, 0x6e, 0x02, 0x43, 0x6f, 0xe6, 0xa9, 0x8a, 0x28,
|
||||
0x04, 0x56, 0xe1, 0x71, 0x72, 0x14, 0x55, 0x5d, 0xf7, 0x5a, 0xfd, 0xb8, 0x5a,
|
||||
0xb1, 0x7a, 0x10, 0x81, 0x01, 0x1a,
|
||||
],
|
||||
auth_digest: [
|
||||
0xee, 0x3a, 0x4a, 0x6d, 0xd3, 0x89, 0xf2, 0x81, 0xb6, 0xd6, 0xe3, 0xd8, 0xe0,
|
||||
0xf7, 0x97, 0xa3, 0xd4, 0xfa, 0x01, 0x4e, 0x3f, 0x41, 0x6a, 0x0e, 0x47, 0x68,
|
||||
0x4f, 0x76, 0x02, 0x15, 0x44, 0x58,
|
||||
0x37, 0xce, 0xcf, 0x21, 0x40, 0x6b, 0xfb, 0x00, 0x2d, 0x1e, 0xde, 0x64, 0x4c,
|
||||
0xff, 0x52, 0xd2, 0x2c, 0x12, 0x36, 0x9f, 0xb4, 0x9e, 0x34, 0xae, 0xf8, 0xa0,
|
||||
0x3b, 0x4b, 0x61, 0xb6, 0x4f, 0xa5,
|
||||
],
|
||||
transparent_input: None,
|
||||
script_code: None,
|
||||
amount: None,
|
||||
sighash_all: [
|
||||
0xad, 0x80, 0x74, 0x56, 0xa6, 0xc0, 0x16, 0x51, 0xf0, 0x80, 0xd1, 0xdd, 0x71,
|
||||
0x87, 0x1f, 0x14, 0x12, 0xe3, 0x8f, 0x89, 0x13, 0x07, 0x52, 0x80, 0xcd, 0x2b,
|
||||
0x38, 0x02, 0xf5, 0xb2, 0x70, 0x4e,
|
||||
0x44, 0x1f, 0xad, 0xb2, 0x5a, 0x6e, 0x02, 0x43, 0x6f, 0xe6, 0xa9, 0x8a, 0x28,
|
||||
0x04, 0x56, 0xe1, 0x71, 0x72, 0x14, 0x55, 0x5d, 0xf7, 0x5a, 0xfd, 0xb8, 0x5a,
|
||||
0xb1, 0x7a, 0x10, 0x81, 0x01, 0x1a,
|
||||
],
|
||||
sighash_none: None,
|
||||
sighash_single: None,
|
||||
|
@ -6567,7 +6567,7 @@ pub mod zip_0244 {
|
|||
},
|
||||
TestVector {
|
||||
tx: vec![
|
||||
0x05, 0x00, 0x00, 0x80, 0x0a, 0x27, 0xa7, 0x26, 0x98, 0xa1, 0x19, 0xf9, 0x8f,
|
||||
0x05, 0x00, 0x00, 0x80, 0x0a, 0x27, 0xa7, 0x26, 0x21, 0x96, 0x51, 0x37, 0x8f,
|
||||
0x50, 0x25, 0x86, 0x83, 0xda, 0xf6, 0x12, 0x02, 0x39, 0x9f, 0xd0, 0x47, 0xee,
|
||||
0xe2, 0x88, 0xbb, 0x45, 0x85, 0x85, 0x1d, 0xc9, 0x3e, 0xcc, 0xc6, 0x23, 0x22,
|
||||
0x92, 0x4c, 0xd1, 0x3b, 0x5d, 0xd4, 0xee, 0xd6, 0x6e, 0xd8, 0xd9, 0x97, 0x2d,
|
||||
|
@ -6578,52 +6578,52 @@ pub mod zip_0244 {
|
|||
0x04, 0x65, 0x00, 0xac, 0x65, 0xaa, 0x1e, 0xa1, 0xb7, 0x00, 0x00, 0x00, 0x00,
|
||||
],
|
||||
txid: [
|
||||
0x0a, 0x8a, 0xef, 0x68, 0x56, 0x9f, 0x90, 0x23, 0xa2, 0xa5, 0xbe, 0xd0, 0x76,
|
||||
0x6d, 0xbc, 0xdf, 0x2d, 0x35, 0xd0, 0x13, 0x55, 0x80, 0x4b, 0xf0, 0xe3, 0xee,
|
||||
0x1b, 0x17, 0xde, 0x9e, 0x46, 0xcd,
|
||||
0x6b, 0x71, 0x52, 0x9c, 0x56, 0x99, 0xb0, 0x64, 0xd8, 0x1b, 0x02, 0x3e, 0xdf,
|
||||
0xf2, 0xb1, 0x02, 0xe6, 0x39, 0x7c, 0x81, 0x24, 0x6c, 0xce, 0x0a, 0x55, 0x61,
|
||||
0xfb, 0x79, 0x5d, 0xd4, 0x88, 0x77,
|
||||
],
|
||||
auth_digest: [
|
||||
0x2c, 0xbe, 0xf7, 0x5b, 0x3e, 0x2c, 0xff, 0x88, 0xb6, 0xf1, 0x20, 0xbf, 0x70,
|
||||
0xcb, 0x3e, 0xc7, 0x57, 0xec, 0x25, 0xd3, 0x11, 0xfa, 0xca, 0xfd, 0xfe, 0x2d,
|
||||
0xb4, 0x2e, 0xd3, 0x42, 0x04, 0x0f,
|
||||
0x07, 0xec, 0x2d, 0xf0, 0xc6, 0xf7, 0x77, 0x15, 0x8d, 0xcb, 0xf7, 0xfc, 0x74,
|
||||
0x08, 0xf2, 0x35, 0xdd, 0xdb, 0x55, 0x7e, 0x4a, 0x48, 0x56, 0xd9, 0x51, 0x90,
|
||||
0xda, 0xb5, 0x59, 0x86, 0x9e, 0xe2,
|
||||
],
|
||||
transparent_input: Some(0),
|
||||
script_code: Some(vec![0x63, 0x52, 0x51, 0x63, 0x53]),
|
||||
amount: Some(107504874564564),
|
||||
sighash_all: [
|
||||
0x96, 0xc2, 0x33, 0x43, 0xe3, 0xa3, 0x69, 0x48, 0xa1, 0xbc, 0x60, 0x29, 0x6e,
|
||||
0xca, 0xaa, 0x71, 0xfd, 0x72, 0xb5, 0x7c, 0x44, 0xad, 0x8e, 0xef, 0x31, 0x87,
|
||||
0x47, 0x7c, 0xcf, 0xe1, 0x62, 0x9d,
|
||||
0x20, 0x6d, 0x56, 0x7f, 0x65, 0xef, 0x19, 0x3f, 0x5a, 0xd7, 0x99, 0x99, 0xd8,
|
||||
0xab, 0x08, 0x56, 0xa0, 0xfa, 0xcc, 0xe6, 0xae, 0x9c, 0xe4, 0x1c, 0x30, 0xf1,
|
||||
0x26, 0xc6, 0x41, 0xbe, 0xb5, 0x1e,
|
||||
],
|
||||
sighash_none: Some([
|
||||
0x27, 0x96, 0x4b, 0xca, 0x78, 0xbf, 0xff, 0x91, 0x8f, 0x5a, 0x4b, 0x6d, 0xa6,
|
||||
0x08, 0x26, 0x8e, 0x56, 0xd2, 0x21, 0x81, 0xa6, 0xf4, 0x3c, 0x64, 0xe5, 0x75,
|
||||
0x9c, 0x18, 0xff, 0xf3, 0x77, 0x9a,
|
||||
0xdf, 0x16, 0x3f, 0x6f, 0x0d, 0x56, 0x7c, 0xfd, 0x97, 0x78, 0xa1, 0x42, 0x5c,
|
||||
0xc8, 0x3d, 0x6e, 0x54, 0x8f, 0xd9, 0x37, 0x43, 0x10, 0x4d, 0x72, 0xfd, 0x7d,
|
||||
0xf5, 0x42, 0xed, 0xaa, 0xe2, 0xb2,
|
||||
]),
|
||||
sighash_single: Some([
|
||||
0x27, 0x96, 0x4b, 0xca, 0x78, 0xbf, 0xff, 0x91, 0x8f, 0x5a, 0x4b, 0x6d, 0xa6,
|
||||
0x08, 0x26, 0x8e, 0x56, 0xd2, 0x21, 0x81, 0xa6, 0xf4, 0x3c, 0x64, 0xe5, 0x75,
|
||||
0x9c, 0x18, 0xff, 0xf3, 0x77, 0x9a,
|
||||
0xdf, 0x16, 0x3f, 0x6f, 0x0d, 0x56, 0x7c, 0xfd, 0x97, 0x78, 0xa1, 0x42, 0x5c,
|
||||
0xc8, 0x3d, 0x6e, 0x54, 0x8f, 0xd9, 0x37, 0x43, 0x10, 0x4d, 0x72, 0xfd, 0x7d,
|
||||
0xf5, 0x42, 0xed, 0xaa, 0xe2, 0xb2,
|
||||
]),
|
||||
sighash_all_anyone: Some([
|
||||
0xcd, 0x13, 0xd5, 0xe0, 0x98, 0x26, 0x2b, 0x9c, 0xaf, 0x39, 0x8a, 0xad, 0x54,
|
||||
0x0d, 0x75, 0x35, 0x6b, 0xd4, 0x63, 0x28, 0xc3, 0x9e, 0xe8, 0xf7, 0xf9, 0x07,
|
||||
0x00, 0xdb, 0x17, 0xf5, 0x15, 0xc3,
|
||||
0x2a, 0xb9, 0x5b, 0x8f, 0xb6, 0xb6, 0x3d, 0xb8, 0x7d, 0x65, 0x0e, 0xad, 0x2b,
|
||||
0x73, 0x89, 0x12, 0x92, 0x31, 0x19, 0x7c, 0xfd, 0x20, 0x0c, 0x8a, 0x44, 0x56,
|
||||
0x96, 0x69, 0xf4, 0x50, 0xc1, 0xe6,
|
||||
]),
|
||||
sighash_none_anyone: Some([
|
||||
0xcd, 0x13, 0xd5, 0xe0, 0x98, 0x26, 0x2b, 0x9c, 0xaf, 0x39, 0x8a, 0xad, 0x54,
|
||||
0x0d, 0x75, 0x35, 0x6b, 0xd4, 0x63, 0x28, 0xc3, 0x9e, 0xe8, 0xf7, 0xf9, 0x07,
|
||||
0x00, 0xdb, 0x17, 0xf5, 0x15, 0xc3,
|
||||
0x2a, 0xb9, 0x5b, 0x8f, 0xb6, 0xb6, 0x3d, 0xb8, 0x7d, 0x65, 0x0e, 0xad, 0x2b,
|
||||
0x73, 0x89, 0x12, 0x92, 0x31, 0x19, 0x7c, 0xfd, 0x20, 0x0c, 0x8a, 0x44, 0x56,
|
||||
0x96, 0x69, 0xf4, 0x50, 0xc1, 0xe6,
|
||||
]),
|
||||
sighash_single_anyone: Some([
|
||||
0xcd, 0x13, 0xd5, 0xe0, 0x98, 0x26, 0x2b, 0x9c, 0xaf, 0x39, 0x8a, 0xad, 0x54,
|
||||
0x0d, 0x75, 0x35, 0x6b, 0xd4, 0x63, 0x28, 0xc3, 0x9e, 0xe8, 0xf7, 0xf9, 0x07,
|
||||
0x00, 0xdb, 0x17, 0xf5, 0x15, 0xc3,
|
||||
0x2a, 0xb9, 0x5b, 0x8f, 0xb6, 0xb6, 0x3d, 0xb8, 0x7d, 0x65, 0x0e, 0xad, 0x2b,
|
||||
0x73, 0x89, 0x12, 0x92, 0x31, 0x19, 0x7c, 0xfd, 0x20, 0x0c, 0x8a, 0x44, 0x56,
|
||||
0x96, 0x69, 0xf4, 0x50, 0xc1, 0xe6,
|
||||
]),
|
||||
},
|
||||
TestVector {
|
||||
tx: vec![
|
||||
0x05, 0x00, 0x00, 0x80, 0x0a, 0x27, 0xa7, 0x26, 0x98, 0xa1, 0x19, 0xf9, 0x02,
|
||||
0x05, 0x00, 0x00, 0x80, 0x0a, 0x27, 0xa7, 0x26, 0x21, 0x96, 0x51, 0x37, 0x02,
|
||||
0x5f, 0x13, 0xec, 0x91, 0x3c, 0x29, 0x02, 0x00, 0x01, 0x78, 0x8f, 0x26, 0x02,
|
||||
0xa2, 0xcf, 0x06, 0x00, 0x01, 0x53, 0x00, 0x00, 0x03, 0x42, 0xf7, 0x36, 0xa0,
|
||||
0xfb, 0x38, 0xae, 0x3e, 0x42, 0xec, 0x67, 0xb0, 0x74, 0x86, 0xf9, 0x0e, 0x60,
|
||||
|
@ -6861,22 +6861,22 @@ pub mod zip_0244 {
|
|||
0x1f, 0x55, 0xeb, 0xca, 0x57, 0xb6, 0x33, 0x7c, 0x85, 0x13,
|
||||
],
|
||||
txid: [
|
||||
0x80, 0xbb, 0x70, 0x2d, 0x71, 0x23, 0x5b, 0xec, 0xbb, 0xa2, 0xa2, 0x51, 0x43,
|
||||
0x51, 0x2a, 0xd9, 0x06, 0x50, 0x34, 0x22, 0x5d, 0xad, 0x9c, 0x89, 0xbf, 0xcb,
|
||||
0x73, 0x32, 0x8d, 0x3d, 0x4f, 0xe6,
|
||||
0x1b, 0x72, 0x8a, 0xf8, 0xd8, 0x7e, 0xeb, 0x9f, 0x7b, 0x87, 0xab, 0xd9, 0x0b,
|
||||
0x5f, 0x4e, 0x93, 0x62, 0x46, 0xad, 0x17, 0x89, 0x31, 0xb4, 0x04, 0x9f, 0x60,
|
||||
0x42, 0x43, 0xa9, 0xaa, 0x54, 0x5c,
|
||||
],
|
||||
auth_digest: [
|
||||
0xbb, 0x48, 0xcf, 0x27, 0x71, 0x54, 0x6c, 0x2c, 0x15, 0x57, 0x7d, 0xb2, 0x0d,
|
||||
0x04, 0x86, 0x5a, 0x8c, 0xc0, 0x0c, 0x9c, 0x02, 0xec, 0xb3, 0x10, 0x24, 0x94,
|
||||
0x31, 0x0f, 0x18, 0x68, 0x50, 0xcf,
|
||||
0x00, 0x23, 0x09, 0x27, 0x5d, 0x8c, 0x01, 0xf1, 0x69, 0xa0, 0x51, 0x2a, 0x3e,
|
||||
0x48, 0xe5, 0x21, 0x81, 0x25, 0xfa, 0x16, 0x1a, 0x87, 0xb4, 0xac, 0xa6, 0x3d,
|
||||
0xaf, 0xe3, 0x12, 0x8e, 0x05, 0x27,
|
||||
],
|
||||
transparent_input: None,
|
||||
script_code: None,
|
||||
amount: None,
|
||||
sighash_all: [
|
||||
0x80, 0xbb, 0x70, 0x2d, 0x71, 0x23, 0x5b, 0xec, 0xbb, 0xa2, 0xa2, 0x51, 0x43,
|
||||
0x51, 0x2a, 0xd9, 0x06, 0x50, 0x34, 0x22, 0x5d, 0xad, 0x9c, 0x89, 0xbf, 0xcb,
|
||||
0x73, 0x32, 0x8d, 0x3d, 0x4f, 0xe6,
|
||||
0x1b, 0x72, 0x8a, 0xf8, 0xd8, 0x7e, 0xeb, 0x9f, 0x7b, 0x87, 0xab, 0xd9, 0x0b,
|
||||
0x5f, 0x4e, 0x93, 0x62, 0x46, 0xad, 0x17, 0x89, 0x31, 0xb4, 0x04, 0x9f, 0x60,
|
||||
0x42, 0x43, 0xa9, 0xaa, 0x54, 0x5c,
|
||||
],
|
||||
sighash_none: None,
|
||||
sighash_single: None,
|
||||
|
@ -6886,7 +6886,7 @@ pub mod zip_0244 {
|
|||
},
|
||||
TestVector {
|
||||
tx: vec![
|
||||
0x05, 0x00, 0x00, 0x80, 0x0a, 0x27, 0xa7, 0x26, 0x98, 0xa1, 0x19, 0xf9, 0x79,
|
||||
0x05, 0x00, 0x00, 0x80, 0x0a, 0x27, 0xa7, 0x26, 0x21, 0x96, 0x51, 0x37, 0x79,
|
||||
0x81, 0x3d, 0x20, 0x21, 0x0c, 0x6f, 0x10, 0x00, 0x03, 0x31, 0xef, 0xba, 0xa1,
|
||||
0xcc, 0xfd, 0x05, 0x00, 0x08, 0x51, 0x53, 0x00, 0xac, 0x52, 0x65, 0xac, 0x65,
|
||||
0x65, 0x7c, 0x6e, 0x39, 0x0e, 0xcf, 0x04, 0x00, 0x09, 0x51, 0x6a, 0xac, 0xac,
|
||||
|
@ -6980,22 +6980,22 @@ pub mod zip_0244 {
|
|||
0x13, 0x05, 0xef, 0x33, 0xd9, 0x73, 0x71, 0x26, 0xd0, 0xe6, 0x62, 0x10,
|
||||
],
|
||||
txid: [
|
||||
0x2f, 0x2a, 0xb7, 0xee, 0xe4, 0xae, 0x1d, 0x52, 0x49, 0xf1, 0x2e, 0xe8, 0x16,
|
||||
0x49, 0x01, 0x54, 0xeb, 0x2d, 0xeb, 0x76, 0x78, 0x74, 0xa3, 0x1b, 0x5d, 0x10,
|
||||
0xaa, 0xf7, 0x6b, 0xa8, 0x4f, 0xae,
|
||||
0x43, 0x67, 0x86, 0x11, 0xad, 0x3e, 0x86, 0x5b, 0x49, 0xc6, 0x6d, 0x5b, 0xcf,
|
||||
0x32, 0xad, 0xce, 0xf1, 0x34, 0x82, 0x29, 0xf1, 0xdc, 0x57, 0x6c, 0xfe, 0x7f,
|
||||
0x79, 0xcf, 0x3d, 0xd2, 0xcf, 0x57,
|
||||
],
|
||||
auth_digest: [
|
||||
0xf1, 0x58, 0x29, 0x64, 0xb8, 0xc9, 0xec, 0x20, 0x29, 0xab, 0x97, 0xa2, 0x55,
|
||||
0x98, 0xdb, 0xff, 0x28, 0x35, 0x23, 0xe6, 0xf3, 0x7a, 0xdb, 0x19, 0xcc, 0x57,
|
||||
0x69, 0xb5, 0x13, 0xc7, 0x33, 0xc0,
|
||||
0x47, 0x37, 0x40, 0x67, 0x05, 0xc0, 0x55, 0x45, 0x75, 0x9e, 0xb8, 0x20, 0x84,
|
||||
0xad, 0xd3, 0xfc, 0xef, 0xd6, 0xb0, 0x98, 0x22, 0x70, 0xf3, 0x57, 0x11, 0xad,
|
||||
0x67, 0x6f, 0x4f, 0xcf, 0x39, 0xdb,
|
||||
],
|
||||
transparent_input: None,
|
||||
script_code: None,
|
||||
amount: None,
|
||||
sighash_all: [
|
||||
0x2f, 0x2a, 0xb7, 0xee, 0xe4, 0xae, 0x1d, 0x52, 0x49, 0xf1, 0x2e, 0xe8, 0x16,
|
||||
0x49, 0x01, 0x54, 0xeb, 0x2d, 0xeb, 0x76, 0x78, 0x74, 0xa3, 0x1b, 0x5d, 0x10,
|
||||
0xaa, 0xf7, 0x6b, 0xa8, 0x4f, 0xae,
|
||||
0x43, 0x67, 0x86, 0x11, 0xad, 0x3e, 0x86, 0x5b, 0x49, 0xc6, 0x6d, 0x5b, 0xcf,
|
||||
0x32, 0xad, 0xce, 0xf1, 0x34, 0x82, 0x29, 0xf1, 0xdc, 0x57, 0x6c, 0xfe, 0x7f,
|
||||
0x79, 0xcf, 0x3d, 0xd2, 0xcf, 0x57,
|
||||
],
|
||||
sighash_none: None,
|
||||
sighash_single: None,
|
||||
|
@ -7005,7 +7005,7 @@ pub mod zip_0244 {
|
|||
},
|
||||
TestVector {
|
||||
tx: vec![
|
||||
0x05, 0x00, 0x00, 0x80, 0x0a, 0x27, 0xa7, 0x26, 0x98, 0xa1, 0x19, 0xf9, 0x12,
|
||||
0x05, 0x00, 0x00, 0x80, 0x0a, 0x27, 0xa7, 0x26, 0x21, 0x96, 0x51, 0x37, 0x12,
|
||||
0x50, 0x92, 0x6f, 0x6a, 0x8e, 0x63, 0x19, 0x03, 0x8f, 0x69, 0xad, 0x9a, 0x91,
|
||||
0x92, 0xb3, 0x02, 0xf2, 0x6b, 0xdd, 0xa4, 0x65, 0xd9, 0x0b, 0x94, 0xb1, 0x2c,
|
||||
0x57, 0xfa, 0x3f, 0xd6, 0x93, 0x00, 0x83, 0xf1, 0x84, 0x43, 0x8d, 0x8a, 0x88,
|
||||
|
@ -7303,47 +7303,47 @@ pub mod zip_0244 {
|
|||
0x5c, 0x25, 0xa1, 0xf6, 0xcd, 0x5a, 0xce, 0x82, 0xc0, 0x0a, 0xb2, 0x34, 0x2b,
|
||||
],
|
||||
txid: [
|
||||
0x16, 0x46, 0x65, 0x05, 0x5e, 0xd5, 0x01, 0x5d, 0xd9, 0xa5, 0x72, 0x47, 0xc2,
|
||||
0x77, 0xde, 0x07, 0x15, 0x27, 0x5d, 0x15, 0x6c, 0xda, 0xb9, 0x6f, 0x68, 0xdc,
|
||||
0x70, 0x10, 0x58, 0x3b, 0x02, 0xaa,
|
||||
0xf2, 0x09, 0x0e, 0xc3, 0xe4, 0xd7, 0x61, 0x3e, 0xee, 0x5d, 0x3a, 0x77, 0xc5,
|
||||
0xd6, 0x4e, 0xea, 0xa2, 0x29, 0xe0, 0xf4, 0x42, 0x74, 0x0c, 0x06, 0x1b, 0x2c,
|
||||
0xb0, 0x8e, 0x93, 0x35, 0xa0, 0x03,
|
||||
],
|
||||
auth_digest: [
|
||||
0x87, 0x46, 0xc9, 0x9d, 0x98, 0x57, 0x86, 0xb1, 0xb7, 0x7c, 0x40, 0x5f, 0x6e,
|
||||
0xe8, 0x31, 0xe2, 0x98, 0x71, 0xca, 0x9d, 0x68, 0xe7, 0x72, 0x4f, 0xb7, 0xf8,
|
||||
0x78, 0x6f, 0x28, 0x18, 0x42, 0xa6,
|
||||
0xb0, 0x9c, 0x87, 0xf9, 0x85, 0x52, 0x9f, 0x8d, 0x51, 0x1d, 0x2c, 0xf0, 0xca,
|
||||
0x42, 0xda, 0xac, 0xea, 0x04, 0x59, 0x18, 0x12, 0x18, 0x90, 0x41, 0x0d, 0x24,
|
||||
0xdb, 0xdc, 0x19, 0x23, 0x96, 0xc6,
|
||||
],
|
||||
transparent_input: Some(0),
|
||||
script_code: Some(vec![]),
|
||||
amount: Some(1405243945822387),
|
||||
sighash_all: [
|
||||
0xc7, 0x07, 0xc7, 0x8f, 0x48, 0x49, 0xc5, 0x49, 0x87, 0x8a, 0xf6, 0x41, 0x50,
|
||||
0x9d, 0xa5, 0x97, 0x87, 0xde, 0x72, 0xff, 0x4e, 0xcd, 0x08, 0xe2, 0x4c, 0x2b,
|
||||
0xa1, 0x0d, 0x11, 0x7b, 0x14, 0xc0,
|
||||
0x84, 0x83, 0xbf, 0x1b, 0x6a, 0xbb, 0x10, 0xa0, 0xce, 0x4a, 0x9a, 0x35, 0xfc,
|
||||
0x1f, 0x56, 0xdf, 0x6e, 0x29, 0xec, 0xd3, 0x4d, 0xf6, 0x52, 0x75, 0xd0, 0x09,
|
||||
0x77, 0xc5, 0x3f, 0x42, 0xf8, 0x91,
|
||||
],
|
||||
sighash_none: Some([
|
||||
0x99, 0xc0, 0xcc, 0x62, 0xe2, 0xa0, 0xb4, 0xf1, 0xb2, 0x83, 0xeb, 0x93, 0x86,
|
||||
0xc9, 0x25, 0x80, 0x41, 0x5a, 0x3a, 0xf1, 0x25, 0x5b, 0xf2, 0x81, 0x74, 0x51,
|
||||
0x9a, 0x3f, 0x07, 0x8a, 0xff, 0x4c,
|
||||
0xc2, 0x0a, 0x39, 0x19, 0x20, 0x96, 0x78, 0xb6, 0x0f, 0x22, 0xee, 0xe4, 0x32,
|
||||
0xc4, 0xf8, 0x9a, 0x1d, 0x4a, 0x8e, 0x08, 0x6e, 0xeb, 0xd6, 0xfc, 0xef, 0x98,
|
||||
0xab, 0x3f, 0x1c, 0x83, 0x61, 0x17,
|
||||
]),
|
||||
sighash_single: Some([
|
||||
0x06, 0x7b, 0x18, 0x22, 0x92, 0xe5, 0x7c, 0xcc, 0x81, 0x0c, 0x01, 0x66, 0x0d,
|
||||
0xf2, 0xdb, 0x4b, 0xda, 0x02, 0x30, 0x1e, 0x3a, 0xf6, 0x6f, 0x87, 0xc9, 0x09,
|
||||
0xda, 0x0a, 0x4f, 0x25, 0x09, 0x86,
|
||||
0x53, 0x98, 0xd8, 0x46, 0x02, 0xae, 0x39, 0xad, 0xdf, 0x98, 0x04, 0x0a, 0xa5,
|
||||
0xdb, 0xfc, 0xfe, 0xc2, 0x66, 0xb5, 0x08, 0xdb, 0xbf, 0xac, 0xf6, 0x3a, 0xdd,
|
||||
0xc3, 0x75, 0x81, 0xef, 0x81, 0x51,
|
||||
]),
|
||||
sighash_all_anyone: Some([
|
||||
0xe3, 0xcb, 0xb8, 0x37, 0x82, 0x5a, 0x1a, 0x34, 0x19, 0x74, 0x39, 0x4b, 0x07,
|
||||
0x2d, 0x8d, 0x1b, 0x1e, 0x6a, 0xa2, 0xab, 0x2b, 0x87, 0xc2, 0x0e, 0x93, 0xf7,
|
||||
0x13, 0x77, 0x2e, 0x3b, 0x3d, 0x9d,
|
||||
0x53, 0x91, 0xce, 0xef, 0xa5, 0x0a, 0x8e, 0x12, 0x1a, 0xa7, 0xb6, 0xde, 0xf7,
|
||||
0xa7, 0x6e, 0x22, 0xcd, 0x81, 0xce, 0x0d, 0x82, 0x6f, 0xd0, 0x40, 0xdc, 0x21,
|
||||
0x6d, 0xe6, 0x7b, 0x01, 0x5b, 0xbd,
|
||||
]),
|
||||
sighash_none_anyone: Some([
|
||||
0xad, 0x36, 0x1a, 0xe8, 0xcd, 0x02, 0x78, 0xf5, 0xe8, 0xf2, 0x30, 0xf8, 0x1a,
|
||||
0x3a, 0xb4, 0x21, 0x9c, 0xf1, 0x56, 0x2d, 0xb6, 0xb4, 0x13, 0x65, 0x44, 0xeb,
|
||||
0xb4, 0x7d, 0x53, 0x73, 0x56, 0xc3,
|
||||
0xe0, 0x9f, 0x3b, 0xe0, 0x44, 0x11, 0x00, 0x81, 0xcf, 0xb8, 0x01, 0xc4, 0x4f,
|
||||
0xf6, 0x38, 0x6c, 0x61, 0x17, 0xaf, 0xd1, 0x42, 0xd3, 0x2a, 0xbe, 0xee, 0x01,
|
||||
0x47, 0xdc, 0xbb, 0x74, 0x77, 0x82,
|
||||
]),
|
||||
sighash_single_anyone: Some([
|
||||
0x00, 0x21, 0x5f, 0x2a, 0xe5, 0x57, 0xfa, 0xca, 0x3b, 0xe0, 0xbb, 0xdd, 0xdc,
|
||||
0x62, 0x69, 0x12, 0x4f, 0x23, 0x26, 0xc7, 0xc0, 0x43, 0xcc, 0xcd, 0xeb, 0x46,
|
||||
0x4c, 0x62, 0x5e, 0x0b, 0xff, 0x56,
|
||||
0x0b, 0xf0, 0x3e, 0x2c, 0xa5, 0x30, 0xf6, 0xac, 0x7d, 0xaa, 0xf4, 0xcc, 0x64,
|
||||
0xf3, 0xe0, 0x26, 0x9b, 0x5b, 0x0b, 0x3e, 0xd6, 0x66, 0xcf, 0x19, 0xe9, 0xd2,
|
||||
0x6f, 0x63, 0x19, 0x1e, 0x0a, 0xfb,
|
||||
]),
|
||||
},
|
||||
]
|
||||
|
|
|
@ -8,6 +8,8 @@ and this library adheres to Rust's notion of
|
|||
## [Unreleased]
|
||||
### Changed
|
||||
- MSRV is now 1.51.0.
|
||||
- Bumped dependencies to `ff 0.11`, `group 0.11`, `bellman 0.11.1`,
|
||||
`bls12_381 0.6`, `jubjub 0.8`.
|
||||
- `zcash_proofs::sapling::SaplingVerificationContext::new` now takes a
|
||||
`zip216_enabled` boolean; this is used to control how RedJubjub signatures are
|
||||
validated.
|
||||
|
|
|
@ -15,14 +15,14 @@ edition = "2018"
|
|||
all-features = true
|
||||
|
||||
[dependencies]
|
||||
bellman = { version = "0.10", default-features = false, features = ["groth16"] }
|
||||
bellman = { version = "0.11.1", default-features = false, features = ["groth16"] }
|
||||
blake2b_simd = "0.5"
|
||||
bls12_381 = "0.5"
|
||||
bls12_381 = "0.6"
|
||||
byteorder = "1"
|
||||
directories = { version = "3", optional = true }
|
||||
ff = "0.10"
|
||||
group = "0.10"
|
||||
jubjub = "0.7"
|
||||
directories = { version = "4", optional = true }
|
||||
ff = "0.11"
|
||||
group = "0.11"
|
||||
jubjub = "0.8"
|
||||
lazy_static = "1"
|
||||
minreq = { version = "2", features = ["https"], optional = true }
|
||||
rand_core = "0.6"
|
||||
|
|
|
@ -1043,35 +1043,32 @@ mod test {
|
|||
assert!(p.assert_not_small_order(&mut cs).is_err() == is_small_order);
|
||||
};
|
||||
|
||||
let check_small_order_from_strs = |u, v| {
|
||||
let (u, v) = (
|
||||
bls12_381::Scalar::from_str(u).unwrap(),
|
||||
bls12_381::Scalar::from_str(v).unwrap(),
|
||||
);
|
||||
let check_small_order_from_u64s = |u, v| {
|
||||
let (u, v) = (bls12_381::Scalar::from(u), bls12_381::Scalar::from(v));
|
||||
let p = jubjub::AffinePoint::from_raw_unchecked(u, v);
|
||||
|
||||
check_small_order_from_p(p.into(), true);
|
||||
};
|
||||
|
||||
// zero has low order
|
||||
check_small_order_from_strs("0", "1");
|
||||
check_small_order_from_u64s(0, 1);
|
||||
|
||||
// prime subgroup order
|
||||
let prime_subgroup_order = jubjub::Fr::from_str(
|
||||
let prime_subgroup_order = jubjub::Fr::from_str_vartime(
|
||||
"6554484396890773809930967563523245729705921265872317281365359162392183254199",
|
||||
)
|
||||
.unwrap();
|
||||
let largest_small_subgroup_order = jubjub::Fr::from_str("8").unwrap();
|
||||
let largest_small_subgroup_order = jubjub::Fr::from(8);
|
||||
|
||||
let (zero_u, zero_v) = (bls12_381::Scalar::zero(), bls12_381::Scalar::one());
|
||||
|
||||
// generator for jubjub
|
||||
let (u, v) = (
|
||||
bls12_381::Scalar::from_str(
|
||||
bls12_381::Scalar::from_str_vartime(
|
||||
"11076627216317271660298050606127911965867021807910416450833192264015104452986",
|
||||
)
|
||||
.unwrap(),
|
||||
bls12_381::Scalar::from_str(
|
||||
bls12_381::Scalar::from_str_vartime(
|
||||
"44412834903739585386157632289020980010620626017712148233229312325549216099227",
|
||||
)
|
||||
.unwrap(),
|
||||
|
|
|
@ -292,11 +292,11 @@ mod test {
|
|||
|
||||
assert_eq!(
|
||||
res.get_u().get_value().unwrap(),
|
||||
bls12_381::Scalar::from_str(expected_us[length - 300]).unwrap()
|
||||
bls12_381::Scalar::from_str_vartime(expected_us[length - 300]).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
res.get_v().get_value().unwrap(),
|
||||
bls12_381::Scalar::from_str(expected_vs[length - 300]).unwrap()
|
||||
bls12_381::Scalar::from_str_vartime(expected_vs[length - 300]).unwrap()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -464,7 +464,7 @@ impl Circuit<bls12_381::Scalar> for Output {
|
|||
// Witness the sign bit
|
||||
let sign_bit = boolean::Boolean::from(boolean::AllocatedBit::alloc(
|
||||
cs.namespace(|| "pk_d bit of u"),
|
||||
pk_d.map(|e| e.get_u().is_odd()),
|
||||
pk_d.map(|e| e.get_u().is_odd().into()),
|
||||
)?);
|
||||
|
||||
// Extend the note with pk_d representation
|
||||
|
@ -703,7 +703,7 @@ fn test_input_circuit_with_bls12_381_external_test_vectors() {
|
|||
for i in 0..10 {
|
||||
let value_commitment = ValueCommitment {
|
||||
value: i,
|
||||
randomness: jubjub::Fr::from_str(&(1000 * (i + 1)).to_string()).unwrap(),
|
||||
randomness: jubjub::Fr::from(1000 * (i + 1)),
|
||||
};
|
||||
|
||||
let proof_generation_key = ProofGenerationKey {
|
||||
|
@ -740,11 +740,11 @@ fn test_input_circuit_with_bls12_381_external_test_vectors() {
|
|||
jubjub::ExtendedPoint::from(value_commitment.commitment()).to_affine();
|
||||
assert_eq!(
|
||||
expected_value_commitment.get_u(),
|
||||
bls12_381::Scalar::from_str(&expected_commitment_us[i as usize]).unwrap()
|
||||
bls12_381::Scalar::from_str_vartime(&expected_commitment_us[i as usize]).unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
expected_value_commitment.get_v(),
|
||||
bls12_381::Scalar::from_str(&expected_commitment_vs[i as usize]).unwrap()
|
||||
bls12_381::Scalar::from_str_vartime(&expected_commitment_vs[i as usize]).unwrap()
|
||||
);
|
||||
let note = Note {
|
||||
value: value_commitment.value,
|
||||
|
|
|
@ -109,7 +109,7 @@ pub(crate) fn to_montgomery_coords(g: ExtendedPoint) -> Option<(Scalar, Scalar)>
|
|||
//
|
||||
// We have that y != 1 above. If x = 0, the only
|
||||
// solutions for y are 1 (contradiction) or -1.
|
||||
if x.is_zero() {
|
||||
if x.is_zero_vartime() {
|
||||
// (0, -1) is the point of order two which is not
|
||||
// the neutral element, so we map it to (0, 0) which is
|
||||
// the only affine point of order 2.
|
||||
|
@ -169,23 +169,20 @@ fn generate_pedersen_circuit_generators() -> Vec<Vec<Vec<(Scalar, Scalar)>>> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ff::PrimeField;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn edwards_d() {
|
||||
// d = -(10240/10241)
|
||||
assert_eq!(
|
||||
-Scalar::from_str("10240").unwrap()
|
||||
* Scalar::from_str("10241").unwrap().invert().unwrap(),
|
||||
-Scalar::from(10240) * Scalar::from(10241).invert().unwrap(),
|
||||
EDWARDS_D
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn montgomery_a() {
|
||||
assert_eq!(Scalar::from_str("40962").unwrap(), MONTGOMERY_A);
|
||||
assert_eq!(Scalar::from(40962), MONTGOMERY_A);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in New Issue