Auto merge of #5266 - daira:zip339, r=daira

ZIP 339 support

Depends on https://github.com/zcash/librustzcash/pull/424 .

Signed-off-by: Daira Hopwood <daira@jacaranda.org>
This commit is contained in:
Homu 2021-08-23 20:41:11 +00:00
commit 4e93c62368
8 changed files with 453 additions and 30 deletions

155
Cargo.lock generated
View File

@ -1,5 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aes"
version = "0.6.0"
@ -93,6 +95,12 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "base64ct"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b"
[[package]]
name = "bech32"
version = "0.8.1"
@ -138,6 +146,20 @@ dependencies = [
"serde",
]
[[package]]
name = "bip0039"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac4d1925000f9183da41ed95477ea815512b5bb7e06e6c6964986ca077e2b75c"
dependencies = [
"hmac",
"pbkdf2",
"rand",
"sha2",
"unicode-normalization",
"zeroize",
]
[[package]]
name = "bitflags"
version = "1.2.1"
@ -294,7 +316,7 @@ checksum = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e"
dependencies = [
"cfg-if 0.1.10",
"crossbeam-channel 0.4.4",
"crossbeam-deque",
"crossbeam-deque 0.7.3",
"crossbeam-epoch 0.8.2",
"crossbeam-queue",
"crossbeam-utils 0.7.2",
@ -331,6 +353,17 @@ dependencies = [
"maybe-uninit",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-epoch 0.9.5",
"crossbeam-utils 0.8.5",
]
[[package]]
name = "crossbeam-epoch"
version = "0.8.2"
@ -397,6 +430,16 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda"
[[package]]
name = "crypto-mac"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714"
dependencies = [
"generic-array",
"subtle",
]
[[package]]
name = "crypto_api"
version = "0.2.2"
@ -488,6 +531,12 @@ dependencies = [
"zeroize",
]
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "endian-type"
version = "0.1.2"
@ -497,7 +546,7 @@ checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d"
[[package]]
name = "equihash"
version = "0.1.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=1a40fc9ac82bf43da15cb36d3757fdf610be1bd2#1a40fc9ac82bf43da15cb36d3757fdf610be1bd2"
source = "git+https://github.com/zcash/librustzcash.git?rev=98dc330cdb1c96e980e62b5bc901edbaa128fea2#98dc330cdb1c96e980e62b5bc901edbaa128fea2"
dependencies = [
"blake2b_simd",
"byteorder",
@ -636,15 +685,14 @@ dependencies = [
[[package]]
name = "halo2"
version = "0.0.1"
source = "git+https://github.com/zcash/halo2.git?rev=d04b532368d05b505e622f8cac4c0693574fbd93#d04b532368d05b505e622f8cac4c0693574fbd93"
source = "git+https://github.com/zcash/halo2.git?rev=27c4187673a9c6ade13fbdbd4f20955530c22d7f#27c4187673a9c6ade13fbdbd4f20955530c22d7f"
dependencies = [
"blake2b_simd",
"crossbeam-utils 0.8.5",
"ff",
"group",
"num_cpus",
"pasta_curves",
"rand",
"rayon",
]
[[package]]
@ -671,6 +719,16 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "hmac"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b"
dependencies = [
"crypto-mac",
"digest",
]
[[package]]
name = "http"
version = "0.2.4"
@ -770,8 +828,7 @@ checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
[[package]]
name = "jubjub"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "593fc4726ca80edb47ee18ab4d826719e25c2096991a79308b44fb915c6014ef"
source = "git+https://github.com/zkcrypto/jubjub.git?rev=96ab4162b83303378eae32a326b54d88b75bffc2#96ab4162b83303378eae32a326b54d88b75bffc2"
dependencies = [
"bitvec",
"bls12_381",
@ -1060,10 +1117,11 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "orchard"
version = "0.0.0"
source = "git+https://github.com/zcash/orchard.git?rev=74df35ce890726478983fb892ff38a5e44ceb08a#74df35ce890726478983fb892ff38a5e44ceb08a"
source = "git+https://github.com/zcash/orchard.git?rev=8454f86d423edbf0b53a1d5d32df1c691f8b7188#8454f86d423edbf0b53a1d5d32df1c691f8b7188"
dependencies = [
"aes",
"arrayvec 0.7.1",
"bigint",
"bitvec",
"blake2b_simd",
"ff",
@ -1124,6 +1182,17 @@ dependencies = [
"winapi",
]
[[package]]
name = "password-hash"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd482dfb8cfba5a93ec0f91e1c0f66967cb2fdc1a8dba646c4f9202c5d05d785"
dependencies = [
"base64ct",
"rand_core 0.6.3",
"subtle",
]
[[package]]
name = "pasta_curves"
version = "0.1.1"
@ -1139,6 +1208,16 @@ dependencies = [
"subtle",
]
[[package]]
name = "pbkdf2"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa"
dependencies = [
"crypto-mac",
"password-hash",
]
[[package]]
name = "pin-project"
version = "1.0.8"
@ -1290,6 +1369,31 @@ dependencies = [
"bitflags",
]
[[package]]
name = "rayon"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
dependencies = [
"autocfg",
"crossbeam-deque 0.8.1",
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
dependencies = [
"crossbeam-channel 0.5.1",
"crossbeam-deque 0.8.1",
"crossbeam-utils 0.8.5",
"lazy_static",
"num_cpus",
]
[[package]]
name = "reddsa"
version = "0.0.0"
@ -1503,6 +1607,21 @@ dependencies = [
"winapi",
]
[[package]]
name = "tinyvec"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "tokio"
version = "1.9.0"
@ -1606,6 +1725,15 @@ version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
[[package]]
name = "unicode-normalization"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-xid"
version = "0.2.2"
@ -1674,7 +1802,7 @@ dependencies = [
[[package]]
name = "zcash_address"
version = "0.0.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=1a40fc9ac82bf43da15cb36d3757fdf610be1bd2#1a40fc9ac82bf43da15cb36d3757fdf610be1bd2"
source = "git+https://github.com/zcash/librustzcash.git?rev=98dc330cdb1c96e980e62b5bc901edbaa128fea2#98dc330cdb1c96e980e62b5bc901edbaa128fea2"
dependencies = [
"bech32",
"blake2b_simd",
@ -1684,7 +1812,7 @@ dependencies = [
[[package]]
name = "zcash_history"
version = "0.2.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=1a40fc9ac82bf43da15cb36d3757fdf610be1bd2#1a40fc9ac82bf43da15cb36d3757fdf610be1bd2"
source = "git+https://github.com/zcash/librustzcash.git?rev=98dc330cdb1c96e980e62b5bc901edbaa128fea2#98dc330cdb1c96e980e62b5bc901edbaa128fea2"
dependencies = [
"bigint",
"blake2b_simd",
@ -1694,7 +1822,7 @@ dependencies = [
[[package]]
name = "zcash_note_encryption"
version = "0.0.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=1a40fc9ac82bf43da15cb36d3757fdf610be1bd2#1a40fc9ac82bf43da15cb36d3757fdf610be1bd2"
source = "git+https://github.com/zcash/librustzcash.git?rev=98dc330cdb1c96e980e62b5bc901edbaa128fea2#98dc330cdb1c96e980e62b5bc901edbaa128fea2"
dependencies = [
"blake2b_simd",
"byteorder",
@ -1708,9 +1836,10 @@ dependencies = [
[[package]]
name = "zcash_primitives"
version = "0.5.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=1a40fc9ac82bf43da15cb36d3757fdf610be1bd2#1a40fc9ac82bf43da15cb36d3757fdf610be1bd2"
source = "git+https://github.com/zcash/librustzcash.git?rev=98dc330cdb1c96e980e62b5bc901edbaa128fea2#98dc330cdb1c96e980e62b5bc901edbaa128fea2"
dependencies = [
"aes",
"bip0039",
"bitvec",
"blake2b_simd",
"blake2s_simd",
@ -1738,7 +1867,7 @@ dependencies = [
[[package]]
name = "zcash_proofs"
version = "0.5.0"
source = "git+https://github.com/zcash/librustzcash.git?rev=1a40fc9ac82bf43da15cb36d3757fdf610be1bd2#1a40fc9ac82bf43da15cb36d3757fdf610be1bd2"
source = "git+https://github.com/zcash/librustzcash.git?rev=98dc330cdb1c96e980e62b5bc901edbaa128fea2#98dc330cdb1c96e980e62b5bc901edbaa128fea2"
dependencies = [
"bellman",
"blake2b_simd",

View File

@ -64,11 +64,12 @@ codegen-units = 1
[patch.crates-io]
ed25519-zebra = { git = "https://github.com/ZcashFoundation/ed25519-zebra.git", rev = "d3512400227a362d08367088ffaa9bd4142a69c7" }
halo2 = { git = "https://github.com/zcash/halo2.git", rev = "d04b532368d05b505e622f8cac4c0693574fbd93" }
halo2 = { git = "https://github.com/zcash/halo2.git", rev = "27c4187673a9c6ade13fbdbd4f20955530c22d7f" }
incrementalmerkletree = { git = "https://github.com/zcash/incrementalmerkletree", rev = "8b59049f1746827ffa3763efa8af948f680491d0" }
orchard = { git = "https://github.com/zcash/orchard.git", rev = "74df35ce890726478983fb892ff38a5e44ceb08a" }
zcash_address = { git = "https://github.com/zcash/librustzcash.git", rev = "1a40fc9ac82bf43da15cb36d3757fdf610be1bd2" }
zcash_history = { git = "https://github.com/zcash/librustzcash.git", rev = "1a40fc9ac82bf43da15cb36d3757fdf610be1bd2" }
zcash_note_encryption = { git = "https://github.com/zcash/librustzcash.git", rev = "1a40fc9ac82bf43da15cb36d3757fdf610be1bd2" }
zcash_primitives = { git = "https://github.com/zcash/librustzcash.git", rev = "1a40fc9ac82bf43da15cb36d3757fdf610be1bd2" }
zcash_proofs = { git = "https://github.com/zcash/librustzcash.git", rev = "1a40fc9ac82bf43da15cb36d3757fdf610be1bd2" }
jubjub = { git = "https://github.com/zkcrypto/jubjub.git", rev = "96ab4162b83303378eae32a326b54d88b75bffc2" }
orchard = { git = "https://github.com/zcash/orchard.git", rev = "8454f86d423edbf0b53a1d5d32df1c691f8b7188" }
zcash_address = { git = "https://github.com/zcash/librustzcash.git", rev = "98dc330cdb1c96e980e62b5bc901edbaa128fea2" }
zcash_history = { git = "https://github.com/zcash/librustzcash.git", rev = "98dc330cdb1c96e980e62b5bc901edbaa128fea2" }
zcash_note_encryption = { git = "https://github.com/zcash/librustzcash.git", rev = "98dc330cdb1c96e980e62b5bc901edbaa128fea2" }
zcash_primitives = { git = "https://github.com/zcash/librustzcash.git", rev = "98dc330cdb1c96e980e62b5bc901edbaa128fea2" }
zcash_proofs = { git = "https://github.com/zcash/librustzcash.git", rev = "98dc330cdb1c96e980e62b5bc901edbaa128fea2" }

View File

@ -0,0 +1,59 @@
#ifndef ZCASH_RUST_INCLUDE_RUST_ZIP339_H
#define ZCASH_RUST_INCLUDE_RUST_ZIP339_H
#include "rust/types.h"
#include <stddef.h>
#include <stdint.h>
#ifndef __cplusplus
#include <assert.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
// These must match src/rust/src/zip339_ffi.rs.
// (They happen to also match the integer values correspond in the bip0039-rs crate with the
// "all-languages" feature enabled, but that's not required.)
enum Language
#ifdef __cplusplus
: uint32_t
#endif
{
English = 0,
SimplifiedChinese = 1,
TraditionalChinese = 2,
Czech = 3,
French = 4,
Italian = 5,
Japanese = 6,
Korean = 7,
Portuguese = 8,
Spanish = 9,
SIZE_HACK = 0xFFFFFFFF // needed when compiling as C
};
static_assert(sizeof(Language) == 4);
/// Creates a phrase with the given entropy, in the given `Language`. The phrase is represented as
/// a pointer to a null-terminated C string that must not be written to, and must be freed by
/// `zip339_free_phrase`.
const char * zip339_entropy_to_phrase(Language language, const uint8_t *entropy, size_t entropy_len);
/// Frees a phrase returned by `zip339_entropy_to_phrase`.
void zip339_free_phrase(const char *phrase);
/// Returns `true` if the given string is a valid mnemonic phrase in the given `Language`.
bool zip339_validate_phrase(Language language, const char *phrase);
/// Copies the seed for the given phrase into the 64-byte buffer `buf`.
/// Returns true if successful, false on error. In case of error, `buf` is zeroed.
bool zip339_phrase_to_seed(Language language, const char *phrase, uint8_t (*buf)[64]);
#ifdef __cplusplus
}
#endif
#endif // ZCASH_RUST_INCLUDE_RUST_ZIP339_H

View File

@ -72,6 +72,7 @@ mod address_ffi;
mod history_ffi;
mod orchard_ffi;
mod transaction_ffi;
mod zip339_ffi;
mod test_harness_ffi;

View File

@ -10,6 +10,7 @@ mod key_components;
mod mmr;
mod notes;
mod signatures;
mod zip339;
#[test]
fn sapling_generators() {

View File

@ -0,0 +1,120 @@
use libc::c_char;
use std::{
convert::{TryFrom, TryInto},
ffi::CStr,
ptr,
};
use crate::zip339_ffi::{
zip339_entropy_to_phrase, zip339_free_phrase, zip339_phrase_to_seed, zip339_validate_phrase,
Language,
};
use zcash_primitives::zip339;
#[test]
fn test_try_from_language() {
assert_eq!(Language(0).try_into(), Ok(zip339::Language::English));
assert!(zip339::Language::try_from(Language(1234)).is_err());
}
#[test]
#[should_panic]
fn test_null_entropy_to_phrase_panics() {
zip339_entropy_to_phrase(Language(0), ptr::null(), 0);
}
#[test]
fn test_free_null_phrase_is_noop() {
zip339_free_phrase(ptr::null_mut());
}
#[test]
#[should_panic]
fn test_validate_null_phrase_panics() {
zip339_validate_phrase(Language(0), ptr::null());
}
#[test]
#[should_panic]
fn test_null_phrase_to_seed_panics() {
zip339_phrase_to_seed(Language(0), ptr::null(), ptr::NonNull::dangling().as_ptr());
}
#[test]
#[should_panic]
fn test_phrase_to_seed_with_null_buffer_panics() {
zip339_phrase_to_seed(
Language(0),
ptr::NonNull::dangling().as_ptr(),
ptr::null_mut(),
);
}
#[test]
fn test_known_answers() {
let mut entropy = [0u8; 32];
// English and another language with non-Latin script.
let expected_phrase_en = "abandon abandon abandon abandon abandon abandon abandon abandon \
abandon abandon abandon abandon abandon abandon abandon abandon \
abandon abandon abandon abandon abandon abandon abandon art";
let expected_phrase_ko = "가격 가격 가격 가격 가격 가격 가격 가격 \
\
";
let expected_seed_en = [
0x40, 0x8B, 0x28, 0x5C, 0x12, 0x38, 0x36, 0x00, 0x4F, 0x4B, 0x88, 0x42, 0xC8, 0x93, 0x24,
0xC1, 0xF0, 0x13, 0x82, 0x45, 0x0C, 0x0D, 0x43, 0x9A, 0xF3, 0x45, 0xBA, 0x7F, 0xC4, 0x9A,
0xCF, 0x70, 0x54, 0x89, 0xC6, 0xFC, 0x77, 0xDB, 0xD4, 0xE3, 0xDC, 0x1D, 0xD8, 0xCC, 0x6B,
0xC9, 0xF0, 0x43, 0xDB, 0x8A, 0xDA, 0x1E, 0x24, 0x3C, 0x4A, 0x0E, 0xAF, 0xB2, 0x90, 0xD3,
0x99, 0x48, 0x08, 0x40,
];
let expected_seed_ko = [
0xD6, 0x93, 0x5F, 0x34, 0x3A, 0xC6, 0x66, 0x97, 0x58, 0x06, 0xDF, 0xA7, 0xBD, 0x0E, 0x45,
0xF8, 0x3A, 0x6F, 0x0A, 0x1A, 0x9F, 0x48, 0x54, 0xF4, 0x40, 0xEC, 0x09, 0x0B, 0xE3, 0xEF,
0x16, 0xEA, 0x09, 0x42, 0x03, 0xEC, 0x07, 0xA1, 0x7D, 0x8B, 0x43, 0x9B, 0xBD, 0x2F, 0x89,
0x3D, 0xB8, 0xB8, 0x3D, 0x3E, 0x43, 0xD4, 0x59, 0xA3, 0x6C, 0x29, 0xDF, 0xAB, 0xC2, 0xF9,
0xF5, 0xB2, 0x47, 0x72,
];
for &(expected_phrase, expected_seed, language) in [
(expected_phrase_en, expected_seed_en, Language(0)),
(expected_phrase_ko, expected_seed_ko, Language(7)),
]
.iter()
{
// Testing these all together simplifies memory management in the test code.
// test zip339_entropy_to_phrase
let phrase = zip339_entropy_to_phrase(language, entropy[..].as_mut_ptr(), 32);
assert_eq!(
unsafe { CStr::from_ptr(phrase) }.to_str().unwrap(),
expected_phrase
);
// test zip339_validate_phrase
assert!(zip339_validate_phrase(language, phrase));
assert!(!zip339_validate_phrase(Language(1), phrase));
assert!(!zip339_validate_phrase(Language(1234), phrase));
// test zip339_phrase_to_seed
let mut seed = [0u8; 64];
assert!(zip339_phrase_to_seed(
language,
phrase,
seed[..].as_mut_ptr()
));
assert_eq!(seed, expected_seed);
// test that zip339_phrase_to_seed zeros buffer on failure
let mut seed = [0xFFu8; 64];
assert!(!zip339_phrase_to_seed(
Language(1),
phrase,
seed[..].as_mut_ptr()
));
assert_eq!(seed, [0u8; 64]);
zip339_free_phrase(phrase as *mut c_char);
}
}

111
src/rust/src/zip339_ffi.rs Normal file
View File

@ -0,0 +1,111 @@
use libc::{c_char, size_t};
use std::{
convert::{TryFrom, TryInto},
ffi::{CStr, CString},
ptr, slice,
};
use zcash_primitives::zip339;
// It's safer to use a wrapper type here than an enum. We can't stop a C caller from passing
// an unrecognized value as a `language` parameter; if it were an enum on the Rust side,
// then that would immediately be UB, whereas this way we can return null or false.
#[repr(C)]
#[derive(Copy, Clone)]
pub struct Language(pub u32);
impl TryFrom<Language> for zip339::Language {
type Error = ();
fn try_from(language: Language) -> Result<Self, ()> {
// These must match `src/rust/include/zip339.h`.
match language {
Language(0) => Ok(zip339::Language::English),
Language(1) => Ok(zip339::Language::SimplifiedChinese),
Language(2) => Ok(zip339::Language::TraditionalChinese),
Language(3) => Ok(zip339::Language::Czech),
Language(4) => Ok(zip339::Language::French),
Language(5) => Ok(zip339::Language::Italian),
Language(6) => Ok(zip339::Language::Japanese),
Language(7) => Ok(zip339::Language::Korean),
Language(8) => Ok(zip339::Language::Portuguese),
Language(9) => Ok(zip339::Language::Spanish),
Language(_) => Err(()),
}
}
}
/// Creates a phrase with the given entropy, in the given `Language`. The phrase is represented as
/// a pointer to a null-terminated C string that must not be written to, and must be freed by
/// `zip339_free_phrase`.
#[no_mangle]
pub extern "C" fn zip339_entropy_to_phrase(
language: Language,
entropy: *const u8,
entropy_len: size_t,
) -> *const c_char {
assert!(!entropy.is_null());
if let Ok(language) = language.try_into() {
let entropy = unsafe { slice::from_raw_parts(entropy, entropy_len) }.to_vec();
if let Ok(mnemonic) = zip339::Mnemonic::from_entropy_in(language, entropy) {
if let Ok(phrase) = CString::new(mnemonic.phrase()) {
return phrase.into_raw() as *const c_char;
}
}
}
ptr::null()
}
/// Frees a phrase returned by `zip339_entropy_to_phrase`.
#[no_mangle]
pub extern "C" fn zip339_free_phrase(phrase: *const c_char) {
if !phrase.is_null() {
unsafe {
// It is correct to cast away const here; the memory is not actually immutable.
CString::from_raw(phrase as *mut c_char);
}
}
}
/// Returns `true` if the given string is a valid mnemonic phrase in the given `Language`.
#[no_mangle]
pub extern "C" fn zip339_validate_phrase(language: Language, phrase: *const c_char) -> bool {
assert!(!phrase.is_null());
if let Ok(language) = language.try_into() {
if let Ok(phrase) = unsafe { CStr::from_ptr(phrase) }.to_str() {
return zip339::Mnemonic::validate_in(language, phrase).is_ok();
}
}
false
}
/// Copies the seed for the given phrase into the 64-byte buffer `buf`.
/// Returns true if successful, false on error. In case of error, `buf` is zeroed.
#[no_mangle]
pub extern "C" fn zip339_phrase_to_seed(
language: Language,
phrase: *const c_char,
buf: *mut u8,
) -> bool {
assert!(!phrase.is_null());
assert!(!buf.is_null());
if let Ok(language) = language.try_into() {
if let Ok(phrase) = unsafe { CStr::from_ptr(phrase) }.to_str() {
if let Ok(mnemonic) = zip339::Mnemonic::from_phrase_in(language, phrase) {
// Use the empty passphrase.
let seed = mnemonic.to_seed("");
unsafe {
ptr::copy(seed.as_ptr(), buf, 64);
}
return true;
}
}
}
unsafe {
ptr::write_bytes(buf, 0, 64);
}
false
}

View File

@ -1,14 +1,15 @@
[
["From https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/unified_address.py"],
["p2pkh_bytes, p2sh_bytes, sapling_raw_addr, orchard_raw_addr, unified_addr"],
[null, "7a8f739a2d9e945b0ce152a8049e294c4d6e66b1", null, "dcb1d2a37762148db4cee3bbf19fb1ec05891894b13801c622ba6a90faf1119f8224ae3985c6abd3b7bbae", "753178356b66326a646c37396b7170653964757a7a3979667a796a726437327364613671657032393265367a336c6c61767270796a6d7674363436306e6733667163773672636479656e6468756a6834643263767979357432687878347364787973326d76346767637a64327a676e73616166707835706173673532646d3237306574757a3778797877657539"],
["b3534201cfb1cd8dbf69b8250c18ef41294ca979", null, "902b6565a1c44e7e7a080571af1dd774697cc126f1fc0435d3cdbf868783e9fb4620df4bf175cbf2c3e36f", "05f61273a7201295332fee4579474534809a0aeb817a2bc0594166ad7a462067712533b6eec0fa2d1be99f", "7531383863733339306532376632346877676468396573756532796b73386c3230743271367864686a39646d32396c3877376d34726438336473706d72743271336435746e36376e367379736e7438306872387a676e6377376b38386735306e6376367874653835676b676e707a79647037747367677166343533723464787164356d6b78757561377938343871747a65383365763777366a676d6a7738363935793475337a7778326671637a6b6875687938356a6764746a72343339366a6d6467643937383768663739783634786b32646e6a70"],
[null, "e8c7203d996af7d477083756d59af80d06a745f4", null, "4ea7d6b3dfa338192af06cbbf47ad405715bc7832bedb1466217dc0d93314de9f3c25eec89f9a21bfe0e93", "753179763478336d786e3364787a3033746b76336575646861683878637838366d6633717667326a397a6c61656a676b716c366633797a6d6e7479387576363868366774616a38677a676c71676d7775723061646b686765307671636e74617668393335307437387a79637772346c363463746633716e3934637472797338356e6c3476306c77383270767173"],
[null, null, "02f1536b622c01346742d8f90e9d4ff39137f1bebe6e23ad9971776b3372702494cc08951eef032b35350f", null, "753135716632787236373076337971796b6374397663716c7935687079766b6d68386b3371636c7135367664686d7030386336717a30726c6e763467307168613975736e6c37336b713539376838763363377274717765303575326836637035706374767a7a346c7463"],
[null, "183e31d49f25c9a138f49b1a537edcf04be34a98", "3246b59a5b492dab1855cc176bddfa28418f11f97f7b361cc3e8834b2c30d2a1717df323ef98ea7de71d2e", "ab6d26252c521547049de208283d96278bb221a6874cb5a86af1d3f8b3db3fbee3dbefedcb2c71e3ca1ead", "753130657a616879367071307034687a65703666376564706775376c67777530796372366c6c6463796a36713530356e67617672706b766534357461396861776571666c3361763768323977346d633777636a7a3871686a797132726e6d6861387271716b34616d3861713461346a6d743263326e6a37746368653765647571367968613536766b73343971706c77786b707761333666676864367036336c796763706339796774773964617630786366326d787270387530367474683468676732383937307368796468637871796a79726b3235"],
[null, null, "970dc3450d34554141d356cb548056279c57708fa73bd16ffe9a2e24ea694898a7b8af1b0ff92585d02623", "0414bb62b86149ee731851f27d532ac0361169da46e6d53d19d3dfd07a5bae22969922d8d0af7dc1e13bae", "753163723077393538346b6133676d6a70687a63636b306736367676786e38723266647566636a707477367534346165327379756b6b6d7a7763716673776b65776e7a6d7a7a7571736c73793733637178706d68336d797967756e6b6e6d73676d746c7a716b7436686e7461687973676a767a77307133707a647865757666747978647a6870726873666a6b3374686e686d706730706834666d36386b7035386d653336386464657066647671356e77726c"],
[null, "098b79535e790fe53e29fef2b3766697ac32b4f4", "a8a8797c1ba69f78672affa65b943975026931ea628431f0991e744872ac9f36946f5dcd6851a0b5af29cf", "678ab0079bea28bf165c1ab976a2a58c18a7811ca2ad0ad649e876273d04325da6ca53cdb83c111e8e4394", "7531676e333576786d3030666b713430636c647a76717372767037336e36726b383036306e6b39686d6c77376535323070346a73757265756b6e757738726c6a7166336e71766130347434326b6e66753071716e39666c6830676e707a766d673868653070747272326e6c38306a787a666178723039656739323035727273727265737a7339306c63633876737561636836773535777334337738637577716d3768736e387234343361617370366d6533327177346c7639666533393978333370783861767865636b656d763976327867366b6e37"],
[null, null, "3509c9e069e89fe501d97622c283ac98923da2d7e6eb346b4bafa67865e1e6dae7cf213b1ea3648dc09b48", null, "753165686465736a6a647370336839376a787a6361766b686433327032706173306a6b333274783577736d707a6a6c35783534306835353335636c6677686b6b686c3367716370726d7779653279793239306a66706378716a71756c616a766a76357571786e7463656e"],
[null, "30d069896cff30eb414f727b89e001afa2fb8dc3", "55bc46aea6f60c1d61915640029b2af6334d7d27e1c47a248ab47c9fbe5d2d7bb5818739f062e37136654c", null, "7531766e63346a336e6a6b377174706a65767764743877347a356e30376b3670363277396a673977796d6a6c7530776d766d7570357579656a61613736646b646778797337653661646e7865636678636e6c39306571366539723035647379353274363976653961756e6b376a773270337477726175686e6c3638346d6e77336332757968616a366c70346c33"],
[null, null, "5c26a8117729334a957ca7941d47b2ce7040e844fa9882c25bfd2fcf51fa8ab21376f5300d0123f5703e9e", null, "75317279687461366d73356a617375396e76653232396d7639383664677a39366a6c37357232716c6d78797061363775657276373834727235306663677567766b646767327773726e7877737378756c77306c7a387735373970746a3239777567383867673577337a73"]
[null, "7a8f739a2d9e945b0ce152a8049e294c4d6e66b1", null, "dcb1d2a37762148db4cee3bbf19fb1ec05891894b13801c622ba6a90faf1119f8224ae3985c6abd3b7bbae", "75316532386638787a6e656d676574797872647a6b66676a756773667839646b713274686e657a65396c333474707674706d656a656774643567686b7768676a7268736466646e74336b34736632757939656138637461756d7a7075646c657a356667756c77716b70753566766a77796374747a79646c383664373434613430617175747a687a7674797a6e68"],
["b3534201cfb1cd8dbf69b8250c18ef41294ca979", null, "902b6565a1c44e7e7a080571af1dd774697cc126f1fc0435d3cdbf868783e9fb4620df4bf175cbf2c3e36f", "05f61273a7201295332fee4579474534809a0aeb817a2bc0594166ad7a462067712533b6eec0fa2d1be99f", "75313371733278796b66737464343332777076366368367336636b683473346833736372746435686b6179367277366a6e3667656e3734726d76636136357775736771653637716d6b6b667a79686c6b7767383071796a33726363616e68356667377a73393032793234676e3271796636706b636363686730356a7a70337972666e3470753861746538673771397239737465767832383434357235776e3378333570663771713332346e746878747a6377786576796661346c326d326d327873376564766570396674613476747776686b617878"],
[null, "e8c7203d996af7d477083756d59af80d06a745f4", null, "4ea7d6b3dfa338192af06cbbf47ad405715bc7832bedb1466217dc0d93314de9f3c25eec89f9a21bfe0e93", "75317270776b64357837746534657a636d6c716172676b66336372737066716b686d787766737170713032346a6173733267373465347233367a70353071737333766863743732736163687573306b37303578796768756c726a786364777764617130716a6e6e737366326676616b7a7a386634367077387263613933366665796566366d6c36657137776c6c"],
[null, null, "02f1536b622c01346742d8f90e9d4ff39137f1bebe6e23ad9971776b3372702494cc08951eef032b35350f", null, "7531396468786d38386776637739747774767a6b7537637a376a753372767075356a766832637138676d38716465766e6c34657365793833667a7239796d666133676a6d6d6b3472786a3279703838677478646b71676e6a366e6e717974667568303875796335667572"],
[null, "183e31d49f25c9a138f49b1a537edcf04be34a98", "3246b59a5b492dab1855cc176bddfa28418f11f97f7b361cc3e8834b2c30d2a1717df323ef98ea7de71d2e", "ab6d26252c521547049de208283d96278bb221a6874cb5a86af1d3f8b3db3fbee3dbefedcb2c71e3ca1ead", "75313563327972666a7774743636336e713068707173683678746a793238387a7476616375616c37336d666675723338336d7465706339687278743374703465613568373830706733686b35756a326775393770326c756d39716a6836327872613763336879366e6471327877686737657138713736766632386333326437766d6c337a323934767438656374636c773672307032336e64703578647a666578633971773065777572796e6a353235736b78376d306a756b636a7265616b6a3261703332376b6a7172767567656435667930737a79"],
[null, null, "970dc3450d34554141d356cb548056279c57708fa73bd16ffe9a2e24ea694898a7b8af1b0ff92585d02623", "0414bb62b86149ee731851f27d532ac0361169da46e6d53d19d3dfd07a5bae22969922d8d0af7dc1e13bae", "75317a6467397a376c7732713037357977396e306a376668387279756a73726a727237347a71783939337463736874666d6d3271786b74763372303438653774723471356a38736665703367396e76387770786639767472336a7a6e6d6d35367a3775706a6530356b7a766d75726d706371703034633033377a32646833356364383232357874336b34376e7a6668327974737630376d337438676433337035723276376b66656739343571376a63306768"],
[null, "098b79535e790fe53e29fef2b3766697ac32b4f4", "a8a8797c1ba69f78672affa65b943975026931ea628431f0991e744872ac9f36946f5dcd6851a0b5af29cf", "678ab0079bea28bf165c1ab976a2a58c18a7811ca2ad0ad649e876273d04325da6ca53cdb83c111e8e4394", "7531796a7733366d7a777a346a643879746e726436676b68376179676d656a3272746c716733766a397965656866646b3233356a657336727170666a6c777167333776346d653575676a6c7a72646e68676c383872726c6567383378386130716d77797a7936393872387675636e346877616772367163657a7373663663683074373466633068766e366d373737687037353761766632636b7a63333239357033323430716c7675707964656c37336c377163746e343063796b357536736573617772367a6d6b746c6a6678687163633765773468"],
[null, null, "3509c9e069e89fe501d97622c283ac98923da2d7e6eb346b4bafa67865e1e6dae7cf213b1ea3648dc09b48", null, "753171786b796d6b68647a6372727a6c79346672717563646b66736e6a377776776c716575306b3466337472706e657a3476777a75686b64616a6b356537363437346d6a34396b75653978396866776566386d34377363633861703933686e6773657567333864706371"],
[null, "30d069896cff30eb414f727b89e001afa2fb8dc3", "55bc46aea6f60c1d61915640029b2af6334d7d27e1c47a248ab47c9fbe5d2d7bb5818739f062e37136654c", null, "75316433726b71777a396b37346b7475766c746e32746d746a36676b6c6739336877733937797473337a75363038766b76673363327973686d6d3330713668386b6434727433733076703475616a776668396137356538613837306e39346c6b70657835617337716e77333436346e7261747563356e35793575766e7a7666326d3466656a687a6576686e306d"],
[null, null, "5c26a8117729334a957ca7941d47b2ce7040e844fa9882c25bfd2fcf51fa8ab21376f5300d0123f5703e9e", null, "75316166617430647574617379666b736161766d34726c336178716e75786c777437363573393476397a716a7430397a793633646c356d6d7970397835636b7672756c6d647134636b6a337272763766396c37756e78666c306438723635383234746773677276673071"]
]