dagenix / rust-crypto Goto Github PK
View Code? Open in Web Editor NEWA (mostly) pure-Rust implementation of various cryptographic algorithms.
License: Apache License 2.0
A (mostly) pure-Rust implementation of various cryptographic algorithms.
License: Apache License 2.0
Would it be possible to split off the hashes into Rust-Hashes or something? I only need SHA1 for instance but currently it's necessary to depend on the whole thing. Very often my library actually breaks because of incompatibilities in parts of rust crypto I am totally not interested in anyways. :)
I request BLAKE2 hash function because it is better, faster, and stronger than MD5: https://leastauthority.com/blog/BLAKE2-harder-better-faster-stronger-than-MD5.html (Disclosure: I'm one of the authors of BLAKE2, and the author of that blog post.)
So, I like crypto that's hard(-er, there's still nonce related foot+gun oportunities) to misuse. djb et al's NaCl library provides nifty crypto_box
/crypto_secretbox
for doing authenticated encryption with a secret key/public key respectfully.
Would people be opposed to having something like this as part of rust-crypto? The issues as far as I am aware are:
As a WIP (though functionally complete and tested) implementation, this could look something like https://github.com/Yawning/rust-crypto/compare/nacl (Don't merge that yet, the way HChaCha was exposed is kind of kludgy). The code is modeled off the C++ API (because the C API is quirky), and is byte compatible.
I wouldn't consider the constructs particularly obscure since they're included in NaCl/tweetNaCl/libsodium/Go's crypto extensions/etc.
Its currently possible to create an AES256 instance with a 16 byte key without getting an error. Also, the IV may not be validated.
Digest
has a handy result_str
function, but for Mac
(eg Hmac
), to just get a hex string, you need to use serialize::hex::ToHex
and do the following:
hmac.result().code().as_slice().to_hex()
This seems very verbose and it would be nice to have a cleaner way to achieve this.
Tested on win32, but I think other 32-bit OS is also problematic:
$ cd /path/to/rust-crypto
$ rustc src/rust-crypto/lib.rs --crate-type=rlib
<inline asm>:3:28: error: register %xmm15 is only available in 64-bit mode
movdqu (%eax), %xmm15
^~~~~~
<inline asm>:8:25: error: register %xmm15 is only available in 64-bit mode
pxor %xmm0, %xmm15
^~~~~~
<inline asm>:14:27: error: register %xmm15 is only available in 64-bit mode
aesenc %xmm0, %xmm15
^~~~~~
<inline asm>:21:31: error: register %xmm15 is only available in 64-bit mode
aesenclast %xmm0, %xmm15
^~~~~~
<inline asm>:24:20: error: register %xmm15 is only available in 64-bit mode
movdqu %xmm15, (%ecx)
^~~~~~
LLVM ERROR: Error parsing inline asm
xmm15 is only available on amd64. The asm code comes from aesni
module.
rustc -O --dep-info src/rust-crypto/lib.rs.d --crate-type=rlib --out-dir . src/rust-crypto/lib.rs
Assertion failed: NewVRegs.empty() && "Cannot append to existing NewVRegs", file d:/Heather/Contrib/P/rust/src/llvm/lib/CodeGen/RegAllocGreedy.cpp, li
ne 2269
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
CBC Decryption could be optimized to use AesSafeDecryptorX8. This would boost performance by almost a factor of 8.
The wikipedia page states it is possible to "efficiently seek to any position in the output stream in constant time." This SO answer seems to indicate that the eSTREAM code uses an IV which contains both the nonce and the offset. The Salsa20
struct in rust-crypto has an offset field, but it is not accessible through normal functions (although I suppose one could initialise the struct oneself with a custom offset).
Am I missing something or is seeking not directly/easily possible when using this library?
The AesSafe AES implementation doesn't work on the most recent rust nightlies. It appears that the is the recent LLVM upgrade in rust-lang/rust@4b22178.
scrypt_simple crashes without an error message if log_n is greater than ~36.
Smaller (but still too large) values fail as expected with:
task '' failed at 'Invalid Scrypt parameters.', src/rust-crypto/scrypt.rs:184
Since all Sha256, Sha384, Sha512 implement the trait Digest and Hmac::new accepts Digest, why do I have an error in this code?
extern crate crypto;
use crypto::sha2::{Sha256, Sha384, Sha512};
use crypto::hmac::Hmac;
use crypto::digest::Digest;
use crypto::mac::Mac;
enum MyType {
Type1,
Type2,
Type3
}
//......
let mut hmac = Hmac::new(match myType {
MyType::Type1 => Sha256::new(),
MyType::Type2 => Sha384::new(),
MyType::Type3 => Sha512::new()
}, my_secret.to_string().as_bytes()
);
The error is:
error: match arms have incompatible types:
expected `crypto::sha2::Sha256`,
found `crypto::sha2::Sha384`
(expected struct `crypto::sha2::Sha256`,
found struct `crypto::sha2::Sha384`) [E0308]
let mut hmac = Hmac::new(match myType {
MyType::Type1 => Sha256::new(),
MyType::Type2 => Sha384::new(),
MyType::Type3 => Sha512::new(),
_ => panic!()
}, my_secret.to_string().as_bytes()
note: match arm with an incompatible type
MyType::Type2 => Sha384::new(),
^~~~~~~~~~~~~
help: methods from traits can only be called if the trait is implemented and in scope; the following traits define a method `input`, perhaps you need to implement one of them:
help: candidate #1: `crypto::cryptoutil::FixedBuffer`
help: candidate #2: `crypto::digest::Digest`
help: candidate #3: `crypto::mac::Mac`
help: methods from traits can only be called if the trait is implemented and in scope; the following traits define a method `result`, perhaps you need to implement one of them:
help: candidate #1: `crypto::digest::Digest`
help: candidate #2: `crypto::mac::Mac`
It would be useful to have fixed_time_eq
as a public function, but the cryptoutil
module is private.
let enc = [0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97];
let key = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c];
let mut dec = vec![0u8; enc.len()];
let mut decryptor = aes::ecb_decryptor(
aes::KeySize::KeySize128,
&key,
blockmodes::NoPadding);
{
let mut read_buf = buffer::RefReadBuffer::new(&enc);
let mut write_buf = buffer::RefWriteBuffer::new(&mut dec);
match decryptor.decrypt(&mut read_buf, &mut write_buf, true) {
Err(why) => panic!("[-] Unable to decrypt data: {:?}", why),
Ok(result) => match result {
buffer::BufferResult::BufferUnderflow => {},
buffer::BufferResult::BufferOverflow => assert!(false),
}
}
}
for cur_byte in dec {
print!("{:02x} ", cur_byte);
}
print!("\n");
$ cargo build && target/debug/crypto-test.exe
6b c1 be e2 2e 40 9f 96 e9 3d 7e 11 73 93 17 2a
$ cargo build --release && target/release/crypto-test.exe
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
I'm guessing this could have something to do with the ASM-implementation being used in the release profile? I'm on Windows using Rust 1.0.0 beta. The decryption subject and key are taken from:
http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors#aes-ecb-128
pub fn keypair(seed: &[u8]) -> ([u8; 64], [u8; 32])
=>
pub fn keypair(seed: &[u8]) -> (Secret, Public)
let foo = keypair(..); .. foo.0 ..
can be non obvious for readers.
I get the following build errors in sha1.rs when building: http://pastebin.com/rMYEGWL6
I am at revision 4b330cd (up-to-date at time of writing).
I guess something changed recently in Rust to trigger this. I was able to build successfully by capturing a std::cell::Cell instead of the value itself, but I'm not convinced that's the best solution!
rust-crypto fails to build on nightly rustc 0.13.0-nightly (ad9e75938 2015-01-05 00:26:28 +0000).
src/http/common.rs:8:16: 8:24 error: unresolved import std::num::Unsigned
. There is no Unsigned
in std::num
src/http/common.rs:8 use std::num::{Unsigned, NumCast, Int, cast};
assert!
is used in many non-testing pub methods like AesGcm::new
, ScryptParams::new
, pub function bcypt
and more.
Wouldn't it be better if those methods/function return an Option
or Result
, instead of crashing the task on illegal parameters?
If the team is understaffed I could help with such change if approved.
Adding Authenticated Encryption with Associated Data modes of operation would be nice, looks like the building blocks to put in GCM mode (though it will require a modified ctr mode) and chacha20/poly1305
in 0.2.3 I get the following error with
rustc --version ⏎ ✭
rustc 0.13.0-nightly (62fb41c32 2014-12-23 02:41:48 +0000)
~/D/r/rust_mnemonic git:master ❯❯❯ cargo build ✭
Compiling rust-crypto v0.2.3
src/rust-crypto/aesni.rs:25:40: 29:10 error: match arms have incompatible types: expected `(_, fn(&[u8], aesni::KeyType, &mut [u8]) {aesni::setup_working_key_aesni_128})`, found `(_, fn(&[u8], aesni::KeyType, &mut [u8]) {aesni::setup_working_key_aesni_192})` (expected fn item, found a different fn item)
src/rust-crypto/aesni.rs:25 let (rounds, setup_function) = match key_size {
src/rust-crypto/aesni.rs:26 KeySize128 => (10, setup_working_key_aesni_128),
src/rust-crypto/aesni.rs:27 KeySize192 => (12, setup_working_key_aesni_192),
src/rust-crypto/aesni.rs:28 KeySize256 => (14, setup_working_key_aesni_256)
src/rust-crypto/aesni.rs:29 };
src/rust-crypto/aesni.rs:27:27: 27:61 note: match arm with an incompatible type
src/rust-crypto/aesni.rs:27 KeySize192 => (12, setup_working_key_aesni_192),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aesni.rs:34:9: 34:23 error: the type of this value must be known in this context
src/rust-crypto/aesni.rs:34 setup_function(key, KeyType::Encryption, e.round_keys.slice_mut(0, size(e.rounds)));
^~~~~~~~~~~~~~
src/rust-crypto/aesni.rs:34:9: 34:92 error: this function takes 1 parameter but 3 parameters were supplied [E0057]
src/rust-crypto/aesni.rs:34 setup_function(key, KeyType::Encryption, e.round_keys.slice_mut(0, size(e.rounds)));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aesni.rs:41:40: 45:10 error: match arms have incompatible types: expected `(_, fn(&[u8], aesni::KeyType, &mut [u8]) {aesni::setup_working_key_aesni_128})`, found `(_, fn(&[u8], aesni::KeyType, &mut [u8]) {aesni::setup_working_key_aesni_192})` (expected fn item, found a different fn item)
src/rust-crypto/aesni.rs:41 let (rounds, setup_function) = match key_size {
src/rust-crypto/aesni.rs:42 KeySize128 => (10, setup_working_key_aesni_128),
src/rust-crypto/aesni.rs:43 KeySize192 => (12, setup_working_key_aesni_192),
src/rust-crypto/aesni.rs:44 KeySize256 => (14, setup_working_key_aesni_256)
src/rust-crypto/aesni.rs:45 };
src/rust-crypto/aesni.rs:43:27: 43:61 note: match arm with an incompatible type
src/rust-crypto/aesni.rs:43 KeySize192 => (12, setup_working_key_aesni_192),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aesni.rs:50:9: 50:23 error: the type of this value must be known in this context
src/rust-crypto/aesni.rs:50 setup_function(key, KeyType::Decryption, d.round_keys.slice_mut(0, size(d.rounds)));
^~~~~~~~~~~~~~
src/rust-crypto/aesni.rs:50:9: 50:92 error: this function takes 1 parameter but 3 parameters were supplied [E0057]
src/rust-crypto/aesni.rs:50 setup_function(key, KeyType::Decryption, d.round_keys.slice_mut(0, size(d.rounds)));
The implementations in this library are of varying code quality. Some look robust, for example the AES-NI implementation. Others look... less robust, for example the fallback pure Rust AES implementation, or any of the ECC implementations.
Would it be worth calling out implementations that are currently "experimental" and use-at-your-own-risk from the ones that can be considered more trustworthy?
Granted this is a rather arbitrary distinction, but perhaps you can come up with a rubric for evaluating whether an implementation is considered "experimental" or not.
I looked at your test for pbkdf2:
#[test]
fn test_pbkdf2() {
let tests = tests();
for t in tests.iter() {
let mut mac = Hmac::new(Sha1::new(), t.password[]);
let mut result = Vec::from_elem(t.expected.len(), 0u8);
pbkdf2(&mut mac, t.salt[], t.c, result[mut]);
assert!(result == t.expected);
}
}
and modified it to this for my purposes, to generate a single key
//where seed_value/mnemonic are both &str
let mut mac = Hmac::new(Sha256::new(),mnemonic.as_bytes());
let mut result = Vec::new();
pbkdf2(&mut mac,seed_value.as_bytes(),PBKDF2_ROUNDS,result[mut]);
however I'm getting an error that the pbkfd2 tests aren't:
src/rust_mnemonic.rs:150:57: 150:69 error: slicing syntax is experimental
src/rust_mnemonic.rs:150 pbkdf2(&mut mac,seed_value.as_bytes(),PBKDF2_ROUNDS,result[mut]);
I'm confused as to why rust-crypto doesn't have the same compiler error that I do?
This is not really an issue with the code, so please forgive me for creating an issue. I'm having trouble with the AES symmetric ciphers and don't know where else I can get input.
For the constructors in aes.rs
, it's not stated if there are any restrictions on the length of the key. AES works with fixed length keys, but maybe the keys are padded when necessary. Same goes for the IV in CBC mode. It should of course be possible to figure these things out by digging through the code. I have tried this and while I am admittedly a newbie in Rust, I haven't managed to figure it out.
The following function does generate a vector of bytes, but can't seem to be decrypted into the original text:
https://gist.github.com/marcusklaas/a0f8e67caa3eb7c54a80
Is this not the idiomatic way of doing AES encryption in rust_crypto? Any pointers would be massively appreciated!
This is where examples could be of great assistance!
getting the following error after building with the rust nightly.
~/D/r/rust_mnemonic git:master ❯❯❯ cargo build ⏎ ✱
Compiling rust-crypto v0.1.2
src/rust-crypto/aessafe.rs:167:25: 167:76 error: the trait `core::kinds::Copy` is not implemented for the type `aessafe::Bs8State<u32>`
src/rust-crypto/aessafe.rs:167 sk: [Bs8State(0, 0, 0, 0, 0, 0, 0, 0), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:157:1: 178:2 note: in expansion of define_aes_impl!
src/rust-crypto/aessafe.rs:214:1: 214:58 note: expansion site
src/rust-crypto/aessafe.rs:167:25: 167:76 note: the `Copy` trait is required because the repeated element will be copied
src/rust-crypto/aessafe.rs:167 sk: [Bs8State(0, 0, 0, 0, 0, 0, 0, 0), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:157:1: 178:2 note: in expansion of define_aes_impl!
src/rust-crypto/aessafe.rs:214:1: 214:58 note: expansion site
src/rust-crypto/aessafe.rs:167:25: 167:76 error: the trait `core::kinds::Copy` is not implemented for the type `aessafe::Bs8State<u32>`
src/rust-crypto/aessafe.rs:167 sk: [Bs8State(0, 0, 0, 0, 0, 0, 0, 0), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:157:1: 178:2 note: in expansion of define_aes_impl!
src/rust-crypto/aessafe.rs:215:1: 215:58 note: expansion site
src/rust-crypto/aessafe.rs:167:25: 167:76 note: the `Copy` trait is required because the repeated element will be copied
src/rust-crypto/aessafe.rs:167 sk: [Bs8State(0, 0, 0, 0, 0, 0, 0, 0), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:157:1: 178:2 note: in expansion of define_aes_impl!
src/rust-crypto/aessafe.rs:215:1: 215:58 note: expansion site
src/rust-crypto/aessafe.rs:167:25: 167:76 error: the trait `core::kinds::Copy` is not implemented for the type `aessafe::Bs8State<u32>`
src/rust-crypto/aessafe.rs:167 sk: [Bs8State(0, 0, 0, 0, 0, 0, 0, 0), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:157:1: 178:2 note: in expansion of define_aes_impl!
src/rust-crypto/aessafe.rs:221:1: 221:58 note: expansion site
src/rust-crypto/aessafe.rs:167:25: 167:76 note: the `Copy` trait is required because the repeated element will be copied
src/rust-crypto/aessafe.rs:167 sk: [Bs8State(0, 0, 0, 0, 0, 0, 0, 0), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:157:1: 178:2 note: in expansion of define_aes_impl!
src/rust-crypto/aessafe.rs:221:1: 221:58 note: expansion site
src/rust-crypto/aessafe.rs:167:25: 167:76 error: the trait `core::kinds::Copy` is not implemented for the type `aessafe::Bs8State<u32>`
src/rust-crypto/aessafe.rs:167 sk: [Bs8State(0, 0, 0, 0, 0, 0, 0, 0), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:157:1: 178:2 note: in expansion of define_aes_impl!
src/rust-crypto/aessafe.rs:222:1: 222:58 note: expansion site
src/rust-crypto/aessafe.rs:167:25: 167:76 note: the `Copy` trait is required because the repeated element will be copied
src/rust-crypto/aessafe.rs:167 sk: [Bs8State(0, 0, 0, 0, 0, 0, 0, 0), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:157:1: 178:2 note: in expansion of define_aes_impl!
src/rust-crypto/aessafe.rs:222:1: 222:58 note: expansion site
src/rust-crypto/aessafe.rs:167:25: 167:76 error: the trait `core::kinds::Copy` is not implemented for the type `aessafe::Bs8State<u32>`
src/rust-crypto/aessafe.rs:167 sk: [Bs8State(0, 0, 0, 0, 0, 0, 0, 0), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:157:1: 178:2 note: in expansion of define_aes_impl!
src/rust-crypto/aessafe.rs:228:1: 228:58 note: expansion site
src/rust-crypto/aessafe.rs:167:25: 167:76 note: the `Copy` trait is required because the repeated element will be copied
src/rust-crypto/aessafe.rs:167 sk: [Bs8State(0, 0, 0, 0, 0, 0, 0, 0), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:157:1: 178:2 note: in expansion of define_aes_impl!
src/rust-crypto/aessafe.rs:228:1: 228:58 note: expansion site
src/rust-crypto/aessafe.rs:167:25: 167:76 error: the trait `core::kinds::Copy` is not implemented for the type `aessafe::Bs8State<u32>`
src/rust-crypto/aessafe.rs:167 sk: [Bs8State(0, 0, 0, 0, 0, 0, 0, 0), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:157:1: 178:2 note: in expansion of define_aes_impl!
src/rust-crypto/aessafe.rs:229:1: 229:58 note: expansion site
src/rust-crypto/aessafe.rs:167:25: 167:76 note: the `Copy` trait is required because the repeated element will be copied
src/rust-crypto/aessafe.rs:167 sk: [Bs8State(0, 0, 0, 0, 0, 0, 0, 0), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:157:1: 178:2 note: in expansion of define_aes_impl!
src/rust-crypto/aessafe.rs:229:1: 229:58 note: expansion site
src/rust-crypto/aessafe.rs:254:25: 254:100 error: the trait `core::kinds::Copy` is not implemented for the type `aessafe::Bs8State<aessafe::u32x4>`
src/rust-crypto/aessafe.rs:254 sk: [Bs8State(o!(), o!(), o!(), o!(), o!(), o!(), o!(), o!()), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:244:1: 269:2 note: in expansion of define_aes_impl_x8!
src/rust-crypto/aessafe.rs:305:1: 305:63 note: expansion site
src/rust-crypto/aessafe.rs:254:25: 254:100 note: the `Copy` trait is required because the repeated element will be copied
src/rust-crypto/aessafe.rs:254 sk: [Bs8State(o!(), o!(), o!(), o!(), o!(), o!(), o!(), o!()), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:244:1: 269:2 note: in expansion of define_aes_impl_x8!
src/rust-crypto/aessafe.rs:305:1: 305:63 note: expansion site
src/rust-crypto/aessafe.rs:254:25: 254:100 error: the trait `core::kinds::Copy` is not implemented for the type `aessafe::Bs8State<aessafe::u32x4>`
src/rust-crypto/aessafe.rs:254 sk: [Bs8State(o!(), o!(), o!(), o!(), o!(), o!(), o!(), o!()), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:244:1: 269:2 note: in expansion of define_aes_impl_x8!
src/rust-crypto/aessafe.rs:306:1: 306:63 note: expansion site
src/rust-crypto/aessafe.rs:254:25: 254:100 note: the `Copy` trait is required because the repeated element will be copied
src/rust-crypto/aessafe.rs:254 sk: [Bs8State(o!(), o!(), o!(), o!(), o!(), o!(), o!(), o!()), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:244:1: 269:2 note: in expansion of define_aes_impl_x8!
src/rust-crypto/aessafe.rs:306:1: 306:63 note: expansion site
src/rust-crypto/aessafe.rs:254:25: 254:100 error: the trait `core::kinds::Copy` is not implemented for the type `aessafe::Bs8State<aessafe::u32x4>`
src/rust-crypto/aessafe.rs:254 sk: [Bs8State(o!(), o!(), o!(), o!(), o!(), o!(), o!(), o!()), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:244:1: 269:2 note: in expansion of define_aes_impl_x8!
src/rust-crypto/aessafe.rs:312:1: 312:63 note: expansion site
src/rust-crypto/aessafe.rs:254:25: 254:100 note: the `Copy` trait is required because the repeated element will be copied
src/rust-crypto/aessafe.rs:254 sk: [Bs8State(o!(), o!(), o!(), o!(), o!(), o!(), o!(), o!()), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:244:1: 269:2 note: in expansion of define_aes_impl_x8!
src/rust-crypto/aessafe.rs:312:1: 312:63 note: expansion site
src/rust-crypto/aessafe.rs:254:25: 254:100 error: the trait `core::kinds::Copy` is not implemented for the type `aessafe::Bs8State<aessafe::u32x4>`
src/rust-crypto/aessafe.rs:254 sk: [Bs8State(o!(), o!(), o!(), o!(), o!(), o!(), o!(), o!()), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:244:1: 269:2 note: in expansion of define_aes_impl_x8!
src/rust-crypto/aessafe.rs:313:1: 313:63 note: expansion site
src/rust-crypto/aessafe.rs:254:25: 254:100 note: the `Copy` trait is required because the repeated element will be copied
src/rust-crypto/aessafe.rs:254 sk: [Bs8State(o!(), o!(), o!(), o!(), o!(), o!(), o!(), o!()), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:244:1: 269:2 note: in expansion of define_aes_impl_x8!
src/rust-crypto/aessafe.rs:313:1: 313:63 note: expansion site
src/rust-crypto/aessafe.rs:254:25: 254:100 error: the trait `core::kinds::Copy` is not implemented for the type `aessafe::Bs8State<aessafe::u32x4>`
src/rust-crypto/aessafe.rs:254 sk: [Bs8State(o!(), o!(), o!(), o!(), o!(), o!(), o!(), o!()), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:244:1: 269:2 note: in expansion of define_aes_impl_x8!
src/rust-crypto/aessafe.rs:319:1: 319:63 note: expansion site
src/rust-crypto/aessafe.rs:254:25: 254:100 note: the `Copy` trait is required because the repeated element will be copied
src/rust-crypto/aessafe.rs:254 sk: [Bs8State(o!(), o!(), o!(), o!(), o!(), o!(), o!(), o!()), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:244:1: 269:2 note: in expansion of define_aes_impl_x8!
src/rust-crypto/aessafe.rs:319:1: 319:63 note: expansion site
src/rust-crypto/aessafe.rs:254:25: 254:100 error: the trait `core::kinds::Copy` is not implemented for the type `aessafe::Bs8State<aessafe::u32x4>`
src/rust-crypto/aessafe.rs:254 sk: [Bs8State(o!(), o!(), o!(), o!(), o!(), o!(), o!(), o!()), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:244:1: 269:2 note: in expansion of define_aes_impl_x8!
src/rust-crypto/aessafe.rs:320:1: 320:63 note: expansion site
src/rust-crypto/aessafe.rs:254:25: 254:100 note: the `Copy` trait is required because the repeated element will be copied
src/rust-crypto/aessafe.rs:254 sk: [Bs8State(o!(), o!(), o!(), o!(), o!(), o!(), o!(), o!()), ..($rounds + 1)]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/aessafe.rs:244:1: 269:2 note: in expansion of define_aes_impl_x8!
src/rust-crypto/aessafe.rs:320:1: 320:63 note: expansion site
src/rust-crypto/fortuna.rs:187:19: 187:45 error: the trait `core::kinds::Copy` is not implemented for the type `fortuna::Pool`
src/rust-crypto/fortuna.rs:187 pool: [Pool::new(), ..NUM_POOLS],
^~~~~~~~~~~~~~~~~~~~~~~~~~
src/rust-crypto/fortuna.rs:187:19: 187:45 note: the `Copy` trait is required because the repeated element will be copied
src/rust-crypto/fortuna.rs:187 pool: [Pool::new(), ..NUM_POOLS],
^~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 13 previous errors
Could not compile `rust-crypto`.
To learn more, run the command again with --verbose.
~/D/r/rust_mnemonic git:master ❯❯❯
Someone ported the kaccak reference implementation to rust. Since it is the winner for SHA-3, it might be within the scope of the project to include an implementation in rust-crypto (even if it's not that implementation)?
I'm very new to rust and just trying to learn how to import and use this crate successfully.
extern crate "rust-crypto" as rust_crypto;
use rust_crypto::md5::Md5;
fn main() {
let mut sh = Md5::new();
sh.input_str("The quick brown fox jumps over the lazy dog");
let out_str = sh.result_str();
println!("{}",out_str);
}
I build it properly with cargo, rust-crypto is being brought in successfully. And looking at the tests written in md5.rs it seems to me like the above should work. What am I doing wrong?
Building under Mavericks OS X.
vanadium:cipher matt$ cargo build
Updating registry https://github.com/rust-lang/crates.io-index
Downloading rust-crypto v0.2.12
Downloading time v0.1.12
Downloading gcc v0.1.4
Downloading rustc-serialize v0.2.7
Compiling gcc v0.1.4
Compiling rustc-serialize v0.2.7
Compiling time v0.1.12
Build failed, waiting for other jobs to finish...
Only -l
and -L
flags are allowed in build script of time v0.1.12
: -L native=/Users/matt/Desktop/Rust experimentation/cipher/target/build/time-7c7fc3eb0c12ad75/out -l time_helpers:static
Any idea why this happens?
Compiling rust-crypto v0.1.0 (https://github.com/DaGenix/rust-crypto#c93829f3)
src/rust-crypto/pbkdf2.rs:146:12: 146:21 error: type `collections::string::String` does not implement any method in scope named `push`
src/rust-crypto/pbkdf2.rs:146 result.push('$');
^~~~~~~~~
src/rust-crypto/pbkdf2.rs:148:12: 148:21 error: type `collections::string::String` does not implement any method in scope named `push`
src/rust-crypto/pbkdf2.rs:148 result.push('$');
^~~~~~~~~
src/rust-crypto/pbkdf2.rs:150:12: 150:21 error: type `collections::string::String` does not implement any method in scope named `push`
src/rust-crypto/pbkdf2.rs:150 result.push('$');
^~~~~~~~~
src/rust-crypto/scrypt.rs:301:12: 301:21 error: type `collections::string::String` does not implement any method in scope named `push`
src/rust-crypto/scrypt.rs:301 result.push('$');
^~~~~~~~~
src/rust-crypto/scrypt.rs:303:12: 303:21 error: type `collections::string::String` does not implement any method in scope named `push`
src/rust-crypto/scrypt.rs:303 result.push('$');
^~~~~~~~~
src/rust-crypto/scrypt.rs:305:12: 305:21 error: type `collections::string::String` does not implement any method in scope named `push`
src/rust-crypto/scrypt.rs:305 result.push('$');
^~~~~~~~~
error: aborting due to 6 previous errors
error: aborting due to previous error
Could not compile `rust-crypto`.
$ cargo build
Updating registry https://github.com/rust-lang/crates.io-index
Compiling rustc-serialize v0.2.4
Compiling rust-crypto v0.2.10
src\rust-crypto\blockmodes.rs:1029:15: 1029:16 error: obsolete syntax: |uint| -> bool
closure type syntax
src\rust-crypto\blockmodes.rs:1029 op: |&mut RefReadBuffer, &mut RefWriteBuffer, bool|
^
note: use unboxed closures instead, no type annotation needed
src\rust-crypto\blockmodes.rs:1031:24: 1031:25 error: obsolete syntax: |uint| -> bool
closure type syntax
src\rust-crypto\blockmodes.rs:1031 next_in_len: || -> uint,
^
src\rust-crypto\blockmodes.rs:1032:25: 1032:26 error: obsolete syntax: |uint| -> bool
closure type syntax
src\rust-crypto\blockmodes.rs:1032 next_out_len: || -> uint,
^
src\rust-crypto\blockmodes.rs:1150:20: 1150:21 error: obsolete syntax: |uint| -> bool
closure type syntax
src\rust-crypto\blockmodes.rs:1150 new_enc: || -> E,
^
src\rust-crypto\blockmodes.rs:1151:20: 1151:21 error: obsolete syntax: |uint| -> bool
closure type syntax
src\rust-crypto\blockmodes.rs:1151 new_dec: || -> D) {
^
src\rust-crypto\blockmodes.rs:1200:20: 1200:21 error: obsolete syntax: |uint| -> bool
closure type syntax
src\rust-crypto\blockmodes.rs:1200 new_enc: || -> E,
^
src\rust-crypto\blockmodes.rs:1201:20: 1201:21 error: obsolete syntax: |uint| -> bool
closure type syntax
src\rust-crypto\blockmodes.rs:1201 new_dec: || -> D) {
^
src\rust-crypto\cryptoutil.rs:252:43: 252:44 error: obsolete syntax: |uint| -> bool
closure type syntax
src\rust-crypto\cryptoutil.rs:252 fn input(&mut self, input: &[u8], func: |&[u8]|);
^
note: use unboxed closures instead, no type annotation needed
src\rust-crypto\cryptoutil.rs:406:51: 406:52 error: obsolete syntax: |uint| -> bool
closure type syntax
src\rust-crypto\cryptoutil.rs:406 fn standard_padding(&mut self, rem: uint, func: |&[u8]|);
^
src\rust-crypto\cryptoutil.rs:410:51: 410:52 error: obsolete syntax: |uint| -> bool
closure type syntax
src\rust-crypto\cryptoutil.rs:410 fn standard_padding(&mut self, rem: uint, func: |&[u8]|) {
^
error: aborting due to 10 previous errors
Could not compile rust-crypto
.
To learn more, run the command again with --verbose.
I work on a Mac OSX. It's all in asm, so I won't be too much help.
// test.rs
extern crate crypto="rust-crypto";
use crypto::util::fixed_time_eq;
fn main() {
if fixed_time_eq(
"720fc058654831694a93369422054a3c35ea8294cd34a131d192d564e9b9dfc9".as_bytes(),
"720fc058654831694a93369422054a3c35ea8294cd34a131d192d564e9b9dfc9".as_bytes()
) {
println!("I worked!")
}
}
[1] 2266 segmentation fault ./test
Rust-crypto stopped compiling recently, due to final
becoming a reserved keyword (see rust-lang/rust@1426f58).
I would gladly submit a PR changing functions and variables named final
to something else. I only need to know what that "something else" is :)
I'm going to work on this, but it might take me a few days or weeks, so I'm creating a tracking issue to alert anyone whose toes I might be stepping on.
task 'cryptoutil::test::test_add_bytes_to_bits_overflow' failed at 'Numeric overflow occured.', /home/alex/Code/Rust/rust-crypto/src/rust_crypto/cryptoutil.rs:233
task 'cryptoutil::test::test_add_bytes_to_bits_tuple_overflow' failed at 'Numeric overflow occured.', /home/alex/Code/Rust/rust-crypto/src/rust_crypto/cryptoutil.rs:276
task 'cryptoutil::test::test_add_bytes_to_bits_tuple_overflow2' failed at 'Numeric overflow occured.', /home/alex/Code/Rust/rust-crypto/src/rust_crypto/cryptoutil.rs:257
task 'vec_util::test_mut_chunk_iterator_0' failed at 'assertion failed: size != 0', /home/alex/Code/Rust/rust-crypto/src/rust_crypto/vec_util.rs:63
I've been using rust-crypto for a good while now in a small Rust project, and after a month where I wasn't able to touch it, I came back and updated the Rust compiler and tried to build. Rust-crypto won't build though, the build script fails seeming, ending in this:
thread '
' panicked at 'explicit panic', C:\msys32\home\Machine.cargo\registry\src\github.com-1285ae84e5963aae\gcc-0.3.4\src\lib.rs:380I'm on Windows 8, using the 32bit Rust compiler, installed fresh today (tried both the beta version and the nightly, currently on today's build of the nightly).
As the build seems to be running through on Travis I assume something's wrong with my setup, but I have no idea what I might need to change; apologies if this is a simple fix and I'm wasting your time!
probably should wait until after io reform hits, opening this as a place to discus.
Could we add the following dependencies to Cargo.toml for crates which moved out of the rust tree?
log = "0.1"
regex = "0.1"
When building a project that uses the out of tree versions of these crates I receive warnings such as:
warning: using multiple versions of crate `regex`
/home/drbawb/projects/piper/kyrie/src/main.rs:13:1: 13:21 note: used here
/home/drbawb/projects/piper/kyrie/src/main.rs:13 extern crate crypto;
^~~~~~~~~~~~~~~~~~~~
note: crate name: regex
/home/drbawb/projects/piper/kyrie/src/main.rs:10:1: 10:18 note: used here
/home/drbawb/projects/piper/kyrie/src/main.rs:10 extern crate log;
^~~~~~~~~~~~~~~~~
note: crate name: regex
warning: using multiple versions of crate `log`
/home/drbawb/projects/piper/kyrie/src/main.rs:13:1: 13:21 note: used here
/home/drbawb/projects/piper/kyrie/src/main.rs:13 extern crate crypto;
^~~~~~~~~~~~~~~~~~~~
note: crate name: log
/home/drbawb/projects/piper/kyrie/src/main.rs:10:1: 10:18 note: used here
/home/drbawb/projects/piper/kyrie/src/main.rs:10 extern crate log;
^~~~~~~~~~~~~~~~~
note: crate name: log
Thanks
Hey, I wanted to suggest a rename of the rust-crypto
crate to just crypto
.
It can be done in the Cargo.toml leaving the package name intact by just renaming the crate.
[lib]
# name = "rust-crypto"
name = "crypto"
path = "src/rust-crypto/lib.rs"
All import calls would then be:
// extern crate "rust-crypto" as crypto; // old way
extern crate crypto; // new way
What do you think?
While looking at #167, I was expecting to get some padding related errors that didn't show up.
Hello everyone,
I can't seem to compile the master
branch of rust-crypto
on OSX 10.10.2.
I get several compile errors about rotate_left(s as usize)
expecting u32
instead of usize
in src/md5.rs
:
So I tried removing as usize
. When I do that, I get a compiler error:
These are the version of rustc/cargo I use:
rustc 1.0.0-nightly (fed12499e 2015-03-03) (built 2015-03-03)
cargo 0.0.1-pre-nightly (a58ffd7 2015-02-27) (built 2015-02-27)
Has anyone had similar issues ?
Thanks for your help.
As discussed in #236, having something like this along with the NaCl box primitives will allow significantly easier use of the library, for the "I just want to encrypt/decrypt stuff without shooting myself in the foot with a shotgun" userbase.
This is probably related to #228.
Maybe something like: https://github.com/Yawning/rust-crypto/tree/curve25519_usability
use crypto::curve25519;
use std::rand::{OsRng, Rng};
let mut rng = try!(OsRng::new());
let my_private = curve25519::PrivateKey::new(&mut rng);
let my_public = my_private.as_bytes();
// Send public key to Bob...
let bobs_raw_public = /* a u8 slice with 32 bytes, read it off the network or something. */;
let bobs_public = curve25519::PublicKey::from_bytes(&bobs_raw_public);
let shared_secret = my_private.key_exchange(bobs_public); // <- [u8; 32] that's shared.
// Pass shared_secret through a KDF of your choice (really, use HKDF).
No pull request because the API more than likely could be improved, and it's a quick and dirty thing that tries to get the general idea across.
I think #128 might have broken the crate:
Compiling rust-crypto v0.1.0 (https://github.com/DaGenix/rust-crypto.git#d2899328)
src/rust-crypto/fortuna.rs:51:5: 51:12 error: unresolved import `aessafe::AesSafe256Encryptor`. Maybe a missing `extern crate aessafe`?
src/rust-crypto/fortuna.rs:51 use aessafe::AesSafe256Encryptor;
^~~~~~~
error: aborting due to previous error
Could not compile `rust-crypto`.
I think low level crypto code written in C should eventually be replaced with Rust for its safety guarantees. However, it isn't necessarily straightforward yet to integrate Rust code in a larger C program.
There's plenty of examples of calling C via FFI in Rust, but not many examples of the reverse. How would someone go about safely integrating the rust-crypto library into a C program?
We need to figure out what our policy should be for expirimental algorithms.
My original though for rust-crypto was to not include anything expirimental. I pushed back on including Sha3 for just this reason. However, over time, rust-crypto has begun to include some expirimental algorithms - XChaCha20 / 96 bit nonce support for ChaCha20, and ChaCha20Poly1305 support for example. So, I believe that it is clear both that rust-crypto doesn't have a policy and that it needs one. I will suggest a policy and a rough mechanism to implement the policy. Its all a bit hand-wavey right now - I don't have any code.
The first thing, I think, is to define what "expirimental" means. My proposed definition is that an expirimental algorithm is one that both lacks a formal spec with test vectors from a recognized standards body AND also is not currently in such wide use that it is effectively standardized. AES would be an example of an algorithm with a formal spec from a recognized standars body. BCrypt would be an example of an algorithm in such wide use that it is effectively a standard (I don't think it has a formal standard). ChaCha20Poly1305 would be an example of an algorithm that would be considered expririmental - there is an IETF draft which specified one set of behavior, an implemention in BoringSSL which has different behavior, and I don't believe its in extremely wide use (yet).
My proposed policy is that rust-crypto will accept implementations of expirimental algorithms, but that these algorithms must clearly be marked as such. I'm thinking that it would be possible to use the Cargo features mechanism to require anyone using these implementations to explicitly opt-in to them by declaring the use of a feature such as "with-expirimental-algorithms". In order to be accepted, however, expirimental algorithms must have minimal impact on non-expirimental algorithm code - ideally no impact. Furthermore, expirimental algorithms may be removed if they fail to achieve a standard or wide use or they become a maintenance burden on the rest of the library. When rust-crypto is getting closer to a stable, 1.0 release, all expirimental algorithms may be reviewed again to see if they are appropriate to be included in the library - basically a policy saying that while all contributions are greatly appreciated, to be prepared for work on expirimental algorithms to be at risk of being removed if it will benefit the library as a whole. Finally, rust-crypto will not accept algorithms that are "new ideas". If someone has a great new idea for a completely new algorithm, thats great, but rust-crypto won't be the test bed for that idea.
An extension of the policy could include requiring expirimental algorithms to live in a seperate directory to make it extra clear where their code is. My concern is that that would make some expririmental algorithms very difficult to implement without impacting existing code and without duplicating code needlessly. The support for 96 bit nonces for ChaCha20 is an example - I don't know how that code could be put in another file than the main ChaCha20 code without requiring a lot of duplication of code or significant refactoring of the existing ChaCha20 code (which would break the policy of minimally impacting non-expirimental algorithm support).
Another policy could be to not allow expirimental algorithms into the rust-crypto code base at all. Given that rust-crypto is still a ways from a stable 1.0 release, I don't know that this policy would help stabilize the library all that significantly, though. It would also run the risk of fracturing development of cryptography code in Rust into more libraries which I feel would also be unfortunate.
The rust to_int() and related methods on integers do not check for overflow in the current Rust codebase. Either update the library to work around this, or create a patch against Rust to do these checks.
From http://doc.rust-lang.org/std/fmt/
fmt::Debug implementations should be implemented for all public types. Output will typically represent the internal state as faithfully as possible. The purpose of the Debug trait is to facilitate debugging Rust code. In most cases, using #[derive(Debug)] is sufficient and recommended.
We get loads of these type errors
type &mut [u8]
does not implement any method in scope named unsafe_mut
I will attempt a pull request momentarily on this issue.
I'm having some trouble getting this to work under rustpkg.
~/rust/rust-http/src/examples master:) rustpkg install github.com/DaGenix/rust-crypto
WARNING: The Rust package manager is experimental and may be unstable
warning: missing crate link meta `package_id`, using `rust_crypto` as default
error: Package github.com/DaGenix/rust-crypto depends on rust_crypto, but I don't know how to find it
task '<unnamed>' failed at 'explicit failure', /Users/harish/rust/rust/src/librustpkg/util.rs:500
task '<unnamed>' failed at 'receiving on closed channel', /Users/harish/rust/rust/src/libstd/rt/comm.rs:199
I'm working on a Diffie-Hellman implementation and an RSA implementation. Progress is quite slow, though. If someone else is working on this as well, please let me know so that we can combine our efforts, or, if you have more time to dedicate to it, I can work on something else.
Thanks!
The current version of rust-crypto fails to compile under Rust 1.0.0alpha2. Here is the rustc output:
Compiling rust-crypto v0.2.16
note: write `[..]` instead
note: write `[..]` instead
note: write `[..]` instead
note: write `[..]` instead
note: write `[..]` instead
note: write `[..]` instead
note: write `[..]` instead
note: write `[..]` instead
note: write `[..]` instead
note: write `[..]` instead
note: write `[..]` instead
note: write `[..]` instead
note: write `[..]` instead
note: write `[..]` instead
note: write `[..]` instead
note: write `[..]` instead
note: write `[..]` instead
note: write `[..]` instead
note: write `[..]` instead
note: write `[..]` instead
note: write `[..]` instead
note: write `[..]` instead
src/aessafe.rs:1017:14: 1017:15 error: parameter `T` is never used
src/aessafe.rs:1017 trait Gf8Ops<T> {
^
src/aessafe.rs:1017:14: 1017:15 help: consider removing `T` or using a marker such as `core::marker::PhantomFn`
src/aessafe.rs:1017 trait Gf8Ops<T> {
^
error: aborting due to previous error
Could not compile `rust-crypto`.
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.