iqlusioninc / crates Goto Github PK
View Code? Open in Web Editor NEWA collection of open source Rust crates from iqlusion
Home Page: https://www.iqlusion.io
License: Apache License 2.0
A collection of open source Rust crates from iqlusion
Home Page: https://www.iqlusion.io
License: Apache License 2.0
When building zeroize some of the doc tests are failing when I'm building it on Fedora:
Doc-tests zeroize Running `/usr/bin/rustdoc --edition=2018 --crate-type lib --test /builddir/build/BUILD/zeroize-1.1.0/src/lib.rs --crate-name zeroize -L dependency=/builddir/build/BUILD/zeroize-1.1.0/target/release/deps -L dependency=/builddir/build/BUILD/zeroize-1.1.0/target/release/deps --cfg 'feature="alloc"' --cfg 'feature="default"' --extern zeroize=/builddir/build/BUILD/zeroize-1.1.0/target/release/deps/libzeroize-11008dc878dbf0c5.rlib` running 4 tests test src/lib.rs - (line 75) ... FAILED test src/lib.rs - (line 86) ... FAILED test src/lib.rs - (line 33) ... ok test src/lib.rs - (line 100) ... ok failures: ---- src/lib.rs - (line 75) stdout ---- error: cannot find derive macro `Zeroize` in this scope --> src/lib.rs:79:10 | 7 | #[derive(Zeroize)] | ^^^^^^^ error: cannot find attribute `zeroize` in this scope --> src/lib.rs:80:3 | 8 | #[zeroize(drop)] | ^^^^^^^ error: aborting due to 2 previous errors Couldn't compile the test. ---- src/lib.rs - (line 86) stdout ---- error: cannot find derive macro `Zeroize` in this scope --> src/lib.rs:90:23 | 7 | #[derive(Copy, Clone, Zeroize)] | ^^^^^^^ error: aborting due to previous error Couldn't compile the test. failures: src/lib.rs - (line 75) src/lib.rs - (line 86) test result: FAILED. 2 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out error: test failed, to rerun pass '--doc'
Zeroing a Vec
on Drop
may still leave data on the heap, as internally Vec
may realloc-and-copy the data to the new size.
Is it possible to provide a Vec
-like type which zeros the old data during reallocation?
Custom allocators, or hooks in the (custom) global allocator, may be future possible alternatives.
I believe that a typical realloc
implementation will not copy, but it is by no means guaranteed or even likely to be true in all cases.
Spotted by @cuviper.
zeroize
is a low-level crate and does not guard e.g. against implicitly copying the value. However, people sometimes assume that it does: https://benma.github.io/2020/10/16/rust-zeroize-move.html
While secrecy
crate is recommended in the docs, it's buried below the sales pitch. Perhaps a big warning right at the top that zeroize
is a low-level crate and most people should use secrecy
instead would prevent such misunderstanding.
Zeroize only safely erases data in an option if the option is Some
. So if an option containing sensitive data gets set to None
and then zeroized, this will not be a secure erasure.
Ideally zeroizing should work even for None
options, but if that's not possible the readme should call out this pitfall.
These headers are:
rpmts.h
: Transaction setsrpmfi.h
: File informationWhen either of these headers are enabled (in src/rpmlib-sys.h
), they cause the automatically generated bindgen_test_layout_max_align_t
test to fail. In either case, we get the following failure:
---- bindgen_test_layout_max_align_t stdout ----
thread 'bindgen_test_layout_max_align_t' panicked at 'assertion failed: `(left == right)`
left: `24`,
right: `32`: Size of: max_align_t', target/debug/build/rpmlib-sys-25076a13bc63918f/out/bindings.rs:6564:5
Both of these headers are presently commented out in the binding generator due to these errors.
This is a tracking issue for providing idiomatic Rust bindings to librpmbuild (a low-level RPM builder) and librpmsign (low-level RPM signer).
The basic bindings for these are in place in rpmlib-sys, however these both seem like low-priority bindings compared to rpmlib's core functionality (#13, #14, #15, #16).
Arguably they should be part of a separate crate (e.g. rpmbuild
), if we even build these bindings at all.
Transfer some cion from A to B:
the TypeName
is not support the cosmos-sdk/MsgSend
, because -
is invalid in TypeName
What's the Value
of amount
in the schema which type is Vec<Coin>
, if it is Value::Bytes<Vec<u8>>
, how to encode the Vec<Coin>
to <Vec<u8>>
?
Hi, thanks for this useful crate. Would be nice to pass through Debug, so that containing types can still derive Debug.
Since the Secret
type implements Unpin
it can be moved out of a pin and therefore Pin doesn't help to pin a secret in memory AFAICT. (I might be wrong, I'm not an expert on pinning.)
Pin::into_inner()
would not have been implemented if Secret
didn't implement Unpin
.
use pin_utils::pin_mut;
use secrecy::{ExposeSecret, Secret};
use std::mem;
use std::pin::Pin;
fn use_secret(s: Secret<[u8; 4]>) {
println!("Use secret {:?}", s.expose_secret());
println!("ptr: {:x?}", s.expose_secret().as_ptr());
}
fn main() {
let a = Secret::new(*b"aaaa");
println!("ptr: {:x?}", a.expose_secret().as_ptr());
pin_mut!(a);
println!("Use secret {:?}", a.expose_secret());
let b = Pin::into_inner(a);
// Moves secret even though we pinned it!
let c = mem::replace(b, Secret::new(*b"bbbb"));
use_secret(c);
}
I think the solution would be:
pub struct Secret<S>
where
S: Zeroize,
{
/// Inner secret value
inner_secret: S,
/// Implement `!Unpin`
_p: PhantomPinned,
}
Hi,
We've been working on integrating the zeroize
crate into our libraries but we ended up with a question to which you might or might not have an answer:
We have some code that overall looks like this:
let x = something.into();
let y = SomeType {
bla: blabla.try_into()?,
x
};
The question is - could the compiler optimize that into()
to be after the try_into()?
, thus potentially not performing the into
conversion? The idea is that x
ends up being of type Zeroizing<T>
and thus cleans up the contents when being dropped, but if the conversion doesn't happen the other type doesn't clean up and is then dropped as is.
This is a tracking issue for specifying a BIP32-Ristretto
algorithm, providing an initial implementation in the bip32
crate, and creating test vectors that other implementations can use.
For context, BIP32 is a specification for "hierarchical deterministic wallets", which allows for the derivation of child keys from parent ones. The BIP32 spec supports a "non-hardended derivation" which leverages the commutative properties of elliptic curve points, allowing someone with knowledge of a parent public key to derive corresponding child public keys. Additionally it specifies a "hardened" derivation which relies entirely on secrets known only to the holder of the parent private key.
The original specification was specified for secp256k1 elliptic curve scalars/points, however as Ristretto provides a prime order group, it can be easily adapted to support that as well.
In regard to a concrete implementation in the bip32
crate, the bip32::ExtendedPrivateKey
type is already generic over the scalar type used for private keys (which is already leveraged to support both k256::SecretKey
and k256::ecdsa::VerificationKey
), which would also make it simple to add support for Ristretto as well.
Stay as close as possible to the original BIP32 construction as specified for secp256k1, retaining the same data structures (e.g. 78-byte binary representation of an extended key).
The motivation for this is to keep the implementation for hardware wallets which already have a BIP32 implementation as simple as possible, and allow them to reuse as much existing code as possible, as well as simplifying the conceptual understanding of the protocol.
The original BIP32 uses Base58Check encoding. This has largely been obsoleted by the Bech32 encoding, and its successor Bech32m, which is used for v1+ SegWit addresses.
As the Base58Check and Bech32 encodings have design flaws, the proposed encoding for BIP32-Ristretto addresses is Bech32m, with no specified Base58Check/Bech32 legacy encoding. This hopefully shouldn't be problematic for hardware wallets, which are likely implementing Bech32m for SegWit support.
Proposed extended key prefixes:
rprv
: Ristretto extended private keyrpub
: Ristretto extended public keyThis issue tracks the ability to read RPM package files. Presently no support is available.
Some reference information on the API is available here, courtesy the Fedora RPM Guide:
#11 is fixed, and #19 added transaction set support, so this is ready to work on for any interested takers.
If you have following tuple struct:
#[derive(Zeroize, ZeroizeOnDrop)]
struct MyNum(u8);
The build fails with the following error:
#[derive(Zeroize, ZeroizeOnDrop)]
^^^^^^^ invalid suffix `usize`
This may be because the generated implementation looks like this:
impl Zeroize for MyNum {
fn zeroize(&mut self) {
self.0usize.zeroize()
}
}
Possible reasons:
Recently, this pull request was merged: rust-lang/rust#59421 which introduced this regression: rust-lang/rust#59553
Playground: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=1fdfb92bcacca661092abdce42cf8810
The Zeroize
implementation for Vec
appears to zero out only the len()
, not the capacity()
.
I believe most people would probably expect the capacity()
to be zero'd?
let mut v = Vec::new();
v.push(secret);
v.pop();
assert_eq!(0, v.len());
.. i.e. nothing is wiped here, and probably should be?
A possible implementation would be to resize_with(Default::default())
the Vec
before running the current implementation?
Spotted by @cuviper.
This issue tracks support for installing and upgrading packages. Presently no support is provided.
It seems like the Python API provides some higher-level facilities around this than are available in core rpmlib.
Python API:
//! Presently this crate favors a simple,
no_std
-friendly, safe i.e.
//!forbid(unsafe_code)
-based implementation and does not provide more advanced
//! memory protection mechanisms e.g. ones based onmlock(2)
/mprotect(2)
.
//! We may explore more advanced protection mechanisms in the future.
There is a rust crate https://github.com/darfink/region-rs that acts as a safe cross-platform wrapper for mlock
.
Would you accept a PR to add optional mlock
support for SecretVec
and SecretString
?
NOTE: This is a tracking issue for blockers in rpmlib-sys. A separate issue will be opened for bindgen itself.
bindgen outputs invalid self-referential bindings for /usr/include/popt.h and any headers that include it (see below for list):
error[E0428]: the name `poptOption` is defined multiple times
|
| pub struct poptOption {
| --------------------- previous definition of the type `poptOption` here
...
| pub type poptOption = *mut poptOption;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `poptOption` redefined here
|
= note: `poptOption` must be defined only once in the type namespace of this module
It seems to be trying to create a type alias with the same name as the type it is aliasing:
pub type poptOption = *mut poptOption;
This is a blocker for generating bindings for the following headers (and possibly more):
This issue tracks support for interacting with the RPM database. Presently no support is available.
Some reference information on the API is available here, courtesy the Fedora RPM Guide:
C API:
Python API:
The Python API informs us what the first hurdle will be:
Just about every Python RPM script needs a transaction set.
~~~So, the first step is figuring out how to resolve the bindgen test failure.~~~
~~~If you are interested in helping this issue move forward, the main place to start is investigating #11~~~
#11 is fixed, and #19 added initial support for transaction sets. This is ready to begin working on, if anyone is interested in contributing.
Mapping the RPM database APIs to idiomatic Rust looks fairly straightforward. The main API to the database, beyond a transaction set, is a transaction set iterator, and we all know how much Rust loves iterators. The docs also give clear instructions about the lifetime of memory, including the appropriate times where transaction-related objects should be freed (or don't need to be freed).
Would a PR be accepted that adds the following implementation?
impl<T> From<T: Zeroize> T for Secret<T> {
fn from(val: T) -> Self {
Self::new(val)
}
}
Without testing, I believe that's all the code that's necessary. It would allow simpler usage in some cases, namely methods that accept Into<Secret<T>>
.
On an unrelated note, fn new
in both Secret
and Zeroize
could trivially be const
.
I would find it useful when unit testing equivalence of values which contain secrets.
I can work around it by manually implementing the traits for my structs which contain secrets, but maybe others would find this useful as well.
Perhaps it should be an opt-in feature flag so that it could support more test project configurations?
Building tmkms under Alpine linux (3.8) fails because linux::get_glibc_version
doesn't handle the version output of ldd
for musl-libc.
What happens is that calling ldd --version
is equivalent to ldd
without any arguments, both output the version information and set the exit code to 1, which when wrongly checked by linux::get_glibc_version
the package fails to build with a panic.
I don't think any other modifications are required to make zeroize work with musl-libc.
/ $ ldd
musl libc (x86_64)
Version 1.1.19
Dynamic Program Loader
Usage: ldd [options] [--] pathname
/ $ ldd --version
musl libc (x86_64)
Version 1.1.19
Dynamic Program Loader
Usage: ldd [options] [--] pathname
The "StdTx" name comes from the previous Amino types, however none of the Protobuf types use this name any longer, which means it may be confusing.
Should we consider a different name? Perhaps cosmos-tx
?
Thanks for this crate!
What is your definition of canonical, per platform? Could this be written in the docs and API docs?
The following fence operations could potentially be used to prevent non-volatile reads from being reordered in front of the zeroing operation in a hypothetical future LLVM that does this sort of reordering:
The current zeroize crate documentation contains the following:
Stack/Heap Zeroing Notes
This crate can be used to zero values from either the stack or the heap.
However, be aware several operations in Rust can unintentionally leave copies of data in memory. This includes but is not limited to:
- Moves and Copy
- Heap reallocation when using Vec and String
- Borrowers of a reference making copies of the data
Pin can be leveraged in conjunction with this crate to ensure data kept on the stack isn't moved.
While it's strictly true that Pin
can be used to this effect, I suggest that it's misleading as currently worded because this property only holds for types that are !Unpin
, and therefore does not apply to the vast majority of types found in the wild. In particular the types that the zeroize crate implements Zeroize
for, Option
, Vec
, and String
, all implement Unpin
, as does the Secret
type from the secrecy crate.
I still think there might be merit in describing how Pin
might be useful in conjunction with this crate, but it would probably take a more complete example to demonstrate how it could be done properly (which might be out of scope for the aforementioned document?).
net2
crate has been deprecated; usesocket2
instead
Details | |
---|---|
Status | unmaintained |
Package | net2 |
Version | 0.2.36 |
URL | deprecrated/net2-rs@3350e38 |
Date | 2020-05-01 |
The net2
crate has been deprecated
and users are encouraged to considered socket2
instead.
See advisory page for additional details.
I was wondering if this code could potentially leave a copy of a secret in memory:
let password = SecretString::new(fs::read_to_string(file_path)?);
Because the underlying implementation of read_to_string
might re-allocate the String
and not zeroes the partially-read secret.
Do you have any suggestion?
I would be happy to provide a PR that convert an impl Read
to a SecretString
that would zeroes things between reads if you think that is a good implementation.
Nice library! It's quite useful.
I did run into an issue, though. My expectation was that this pseudo-code should work:
let ref_path = CanonicalPath::new("/foo/bar/").unwrap();
let relative_path = Path::new("../baz");
let abs_path = ref_path.join(&relative_path).expect("This should succeed!");
assert_eq!(CanonicalPath::new("/foo/baz"), abs_path);
In reality, the call to join()
fails. This happens because relative_path
contains ../
and CanonicalPath::join()
just concatenates the two paths and calls CanonicalPathBuf::new()
. Since CanonicalPathBuf::new()
returns Err
if the path is not already canonical, CanonicalPath::join()
does as well. If CanonicalPath::join()
called CanonicalPathBuf::canonicalize()
instead, then this code would work as expected.
For now, I'm using this approach as a workaround:
let abs_path = CanonicalPathBuf::canonicalize(ref_path.as_path().join(&relative_path));
https://crates.io/crates/netconf point to that repo, although it doesn't implement netconf
additionally Doc link is pointing to Rick Astley
Since often pinning is desired in conjunction with Zeroize, it would be nice to have zeroize define a Zeroize implementation for core::marker::PhantomPinned so that derive can be used with structs that contain PhantomPinned to prevent moving.
I can upload a pull request if it would help.
Please add it to the crate zeroize as well.
Having a checked version of strip_prefix
, guaranteed to happen only between two canonical paths, would be very useful.
This would be particularly useful for testing, as we could have a test fixture RPM database which is always in an expected state for testing, and furthermore would be able to test destructive operations.
For our use cases we often want to normalize paths to be least likely to cause interoperability problems between platforms and applications. If a canonical path has to be normalized in this way, we deem it an non-interoperable path. In that case, we could then opt to fail early in some of our processes, e.g. in development pipelines.
For instance, some characters can be used in files on Linux, while they can’t on Windows (e.g., \
or |
). Some characters would better be substituted (e.g., spaces) to be compatible or usable with some applications (e.g., Unix shells). Some filenames are reserved on Windows (e.g., CON
). Some paths would be too long on e.g. Windows. We may want to enforce decodability of the path in some text encoding (e.g. UTF-8), while that isn’t enforced in e.g. Linux.
We plan to make a small wrapper for Path
s and PathBuf
s as well to cover sanity checks along these lines.
Do we share this requirement somehow? If yes, does this fall under the scope of this crate? If yes, and then no, how could we cooperate to achieve optimal code reuse amongst us?
zeroize
v0.8 added an API with an implicit Drop
handler when doing a derive(Zeroize)
.
There are many cases where we'd like to be able to derive(Zeroize)
without a drop handler, such as deriving it on Copy
types what may wind up in a container that we'd like to zeroize, or for the new Zeroizing
feature to clear temporary data on the stack.
For these reasons, v0.9 moved to a new #[zeroize(drop)]
API which makes the derivation explicit. However, this is a potentially dangerous change if anyone is expecting to get one implicitly.
For this reason, I'd like to yank zeroize
v0.8, and give people time to update to v0.9 which presently forces the selection of #[zeroize(drop)]
vs #[zeroize(no_drop)]
.
Once we're confident everyone who was previously using v0.8 has upgraded to v0.9 (say a couple weeks after it's yanked), we can make #[zeroize(no_drop)]
an optional attribute, and eventually phase it out prior to a v1.0.
Am I missing something obvious here, or how is a SecretBox
constructed in practice?
fn foo {
let secret_byte = Box::new(0_u8);
let secret_box = Secret::new(secret_byte);
}
error[E0277]: the trait bound `std::boxed::Box<u8>: zeroize::DefaultIsZeroes` is not satisfied
--> src/handshake.rs:151:37
|
151 | let secret_box = Secret::new(secret_byte);
| ^^^^^^^^^^^ the trait `zeroize::DefaultIsZeroes` is not implemented for `std::boxed::Box<u8>`
|
= note: required because of the requirements on the impl of `zeroize::Zeroize` for `std::boxed::Box<u8>`
= note: required by `secrecy::Secret::<S>::new`
There seems to be an impl missing for Box
.
Hi,
Currently DebugSecret
is implemented only for Vec<S>
, where S
must have DebugSecret
implemented on it as well (link) - however only arrays of types with Debug
have that trait, so only Vec<[T]>
will get DebugSecret
implemented.
I was wondering if it's possible to have DebugSecret
implemented on Vec<S: Debug>
as well/instead.
Would it make sense to provide ZeroizeOnDrop wrapper type? Are there any security considerations with this design? Something like this:
pub struct ZeroizeOnDrop<T: Zeroize>(pub T);
impl<T: Zeroize> Drop for ZeroizeOnDrop<T> {
fn drop(&mut self) {
self.0.zeroize()
}
}
Line 18 in 79a0a98
I wish you reply.
davirain
failure is officially deprecated/unmaintained
Details | |
---|---|
Status | unmaintained |
Package | failure |
Version | 0.1.8 |
URL | rust-lang-deprecated/failure#347 |
Date | 2020-05-02 |
The failure
crate is officially end-of-life: it has been marked as deprecated
by the former maintainer, who has announced that there will be no updates or
maintenance work on it going forward.
The following are some suggested actively developed alternatives to switch to:
See advisory page for additional details.
This issue tracks support for using rpmlib to compare RPM versions, a.k.a. dependency sets. Presently no support is provided.
RPM has all sorts of complicated and fancy rules for comparing package versions and determining which ones are newer. Quoth the Fedora RPM Guide:
You could compare the version numbers directly, calling headerGetEntry to get the version and release tags, converting these strings to numbers and then comparing, but this would cause problems. The custom comparison is not as exact as the code in this section, especially since many packages have version numbers that are not true numbers, such as 1.12.4, with one too many decimal points. This makes the comparisons harder. In addition, there is more than just the version number to take into account. You need to deal with the Epoch value, as well as the release, too.
So, tl;dr: if we ever want to compare RPM versions, we should really use rpmlib's comparison logic to do it.
~~~We really gotta get #11 fixed!~~~
Update: #11 is fixed, and #19 added transaction set support.
I'm looking for support to zero structures from the rand
crate. I'm wondering whether this is possible with the current API the crate provides.
I'd like this because I assume generated random numbers can be derived from the state the random number generator leaves in memory when it is dropped.
For example, I'd like to implement Zeroize
on this struct, but can't do this for Uniform
and ThreadRng
:
https://github.com/timvisee/chbs/blob/d2adc73307f9c4598ee0c9c0f8891bc5854e5331/src/word.rs#L290-L299
Could support for something like this be implemented?
I have to store a password that will be passed to a C API using the Rust FFI. To avoid unnecessary copies, I store it as a std::ffi::CString
. But as Zeroize
is not implemented for CString
, I can’t wrap this field in a Secret
.
Could you please add a Zeroize
implementation for CString
?
See: https://circleci.com/gh/tendermint/kms/360
error: failed to run custom build command for `zeroize v0.4.1`
process didn't exit successfully: `/home/developer/project/target/debug/build/zeroize-5de1c809380e58e7/build-script-build` (exit code: 101)
--- stderr
thread 'main' panicked at 'unsupported standard library', /home/developer/.cargo/registry/src/github.com-1ecc6299db9ec823/zeroize-0.4.1/build.rs:137:21
cc @amrali
I would like to support zeroize on wasm targets. However, zeroize was created with an explicit goal in mind:
No insecure fallbacks
To that end, any solution implemented MUST guarantee execution. Based on my preliminary research, I think there are options available for both stable
and nightly
Rust:
nightly
: The existing wrapper for volatile_set_memory()
, to my understanding, will provide the desired behavior of a volatile zeroing operation using LLVM's volatile semanticsstable
: The aforementioned function is an unstable LLVM intrinsic guarded by a feature flag and is not available on stable. However via Twitter comes a clever idea: at least on WASM targets where the JS bridge is available, call out to JS to clear the buffer. While I'm a bit worried that eventually the WASM <-> JS bridge might potentially be optimized to the point it can see through this an optimize it away, so far based on some preliminary investigation that does not seem to be the case with any existing browser / WASM implementationI'm a bit worried that the "stable" solution is the sort of "clever hack" this crate was created to avoid, although I think it falls into the "good enough for now" category.
Another approach which might work on stable
is to directly emit the WASM necessary to perform a volatile zeroing operation. However, I have never tried that before and wouldn't really know where to start.
Cosmos SDK is migrating to a new transaction format based on Protocol Buffers, which is tracked in the following issue:
Presently the stdtx
crate implements transaction signing using legacy Amino formats (JSON + binary serialization).
This issue is for tracking planning/work on migrating the stdtx
crate to use the new Protobuf-based transaction formats being implemented upstream in the Cosmos SDK.
This is a really minor nitpick, but I wonder whether it might be better to rename ZeroizeWithDefault
to something like DefaultIsZeroes
.
The reason is that "zeroize with default" makes it sound like the objects are wiped by replacing them with the default value (leaving open the possibility that it could be used with any type implementing Default
), when AFAICT it's a marker trait saying that the default value for type is zeroes, and therefore zeroing the memory gives the same result as calling default()
.
So naming the marker trait something like DefaultIsZeroes
seems like it would be more clear for expressing the property attached to the marker trait, without making it sound like a trait that has some extra behaviour.
So I use https://crates.io/crates/cargo-release to manage my releases to crates.io but I found out the versions that it uses result in build failures with cargo-rpm. e.g. https://gitlab.com/cardoe/sakcl/-/jobs/71676981 The style of versioning "0.1.1-alpha.0" is actually proper per https://semver.org/#spec-item-11 which is what Rust and Cargo follow.
I have a few non-public projects that I build with RPMs and build directly with rpmbuild and a shell script that substitutes values in. The process I followed was https://fedoraproject.org/wiki/Packaging:Versioning#Prerelease_versions
Hello,
I am currently developing a library for interacting with the Google Cloud Platform services (repo is here).
I think it will soon be ready to publish on crates.io, so I looked up if the crate name gcp
was free and I saw that the crate is already reserved since late 2018 and its "repository link" links here but there aren't any implementations for a gcp
crate.
So, I wondered whether you planned to use that crate name or if there is a possibility to trade the crate name ?
There is seemingly some bug in the proc macros
error: proc-macro derive panicked
--> zeroize/tests/zeroize_derive.rs:7:14
|
7 | #[derive(Zeroize)]
| ^^^^^^^
|
= help: message: unknown zeroize attribute: (drop)
I must work around this anyways though until dalek adopts zeroize
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.