Removed according to regulations.
shadowsocks / crypto2 Goto Github PK
View Code? Open in Web Editor NEWThe fastest cryptographic library in the galaxy
License: MIT License
The fastest cryptographic library in the galaxy
License: MIT License
Removed according to regulations.
cbc?
As stated in std::slice::from_raw_parts_mut
, behavior is undefined if its input pointer is not properly aligned. xor_si512_inplace
allows creating a u32
slice from a pointer to u8
without fulfilling the alignment requirement, which is possible to cause undefined behavior. With a debug build of libstd
, the call to from_raw_parts_mut
panics.
This affects encryption and decryption of Chacha20 cipher.
I use miscreant.aes.siv in my python script and I'm trying to migrate it to Rust using Crypto2 AES SIV. (miscreant.rs does not support Aes512Cmac now)
Mac and Key are 32bit. So I need the Aes512Cmac. But, It's not the same results.
I think my rust code is something wrong. I tried to figure it out and find it in the Crypto2 documents, but I couldn't.
How can I get the same results correctly like the miscreant-py?
from miscreant.aes.siv import SIV
mac = [210, 74, 211, 191, 98, 164, 14, 238, 213, 192, 46, 64, 133, 107, 253, 41, 115, 180, 47, 142, 210, 48, 204, 114, 122, 55, 36, 204, 135, 225, 178, 130]
key = [232, 50, 179, 61, 118, 166, 202, 75, 10, 83, 158, 144, 212, 124, 251, 51, 71, 61, 233, 200, 200, 21, 19, 53, 41, 66, 242, 96, 230, 20, 194, 195]
print('MAC:', len(mac), [int(i) for i in mac])
print('KEY:', len(key), [int(i) for i in key])
for id in '', 'ff3bb8f2-dd51-4ac6-9c79-cb0ab79c23e5':
siv = SIV(bytes(mac + key))
out = siv.seal(id.encode())
print('ID:', id)
print('OUT:', len(out), [int(i) for i in out])
print()
MAC: 32 [210, 74, 211, 191, 98, 164, 14, 238, 213, 192, 46, 64, 133, 107, 253, 41, 115, 180, 47, 142, 210, 48, 204, 114, 122, 55, 36, 204, 135, 225, 178, 130]
KEY: 32 [232, 50, 179, 61, 118, 166, 202, 75, 10, 83, 158, 144, 212, 124, 251, 51, 71, 61, 233, 200, 200, 21, 19, 53, 41, 66, 242, 96, 230, 20, 194, 195]
ID:
OUT: 16 [248, 84, 15, 233, 58, 91, 208, 105, 201, 101, 161, 127, 136, 242, 21, 134]
ID: ff3bb8f2-dd51-4ac6-9c79-cb0ab79c23e5
OUT: 52 [86, 67, 223, 72, 65, 160, 109, 83, 86, 81, 231, 36, 195, 68, 40, 120, 43, 219, 25, 194, 233, 134, 143, 212, 219, 19, 187, 159, 110, 229, 109, 111, 150, 57, 230, 50, 24, 120, 210, 146, 178, 254, 204, 20, 31, 10, 22, 128, 97, 143, 172, 74]
use crypto2::aeadcipher::AesSivCmac512;
let id = "";
let mac: [u8; 32] = [210, 74, 211, 191, 98, 164, 14, 238, 213, 192, 46, 64, 133, 107, 253, 41, 115, 180, 47, 142, 210, 48, 204, 114, 122, 55, 36, 204, 135, 225, 178, 130];
let key: [u8; 32] = [232, 50, 179, 61, 118, 166, 202, 75, 10, 83, 158, 144, 212, 124, 251, 51, 71, 61, 233, 200, 200, 21, 19, 53, 41, 66, 242, 96, 230, 20, 194, 195];
let mut key = Vec::new();
key.write(mac).unwrap();
key.write(primary_master_key).unwrap();
let cipher = AesSivCmac512::new(&key);
let mut plaintext = Vec::new();
plaintext.write(id.as_bytes()).unwrap();
for _ in 0..AesSivCmac512::TAG_LEN {
plaintext.insert(0, 0);
}
// for _ in 0..16 {
// plaintext.push(0);
// }
cipher.encrypt_slice(&[], &mut plaintext);
println!("KEY {:?}", key);
println!("MAC {:?}", mac);
println!("ID {:?}", id);
println!("OUT {} {:?}", plaintext[AesSivCmac512::TAG_LEN..].len(), &plaintext[AesSivCmac512::TAG_LEN..]);
PLAINTEXT: 16 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
KEY [232, 50, 179, 61, 118, 166, 202, 75, 10, 83, 158, 144, 212, 124, 251, 51, 71, 61, 233, 200, 200, 21, 19, 53, 41, 66, 242, 96, 230, 20, 194, 195]
MAC [210, 74, 211, 191, 98, 164, 14, 238, 213, 192, 46, 64, 133, 107, 253, 41, 115, 180, 47, 142, 210, 48, 204, 114, 122, 55, 36, 204, 135, 225, 178, 130]
ID ""
OUT 0 []
大神,您的 crypto 库真心地佬强大了。
crypto2 = {git = "https://github.com/shadowsocks/crypto", branch = "master", package = "crypto"}
其次,我在使用其提供的 sm4 - cbc 模式时,注意到被加密【明文】(utf-8 英文字母,数字与下划线)的长度必须是 16 的整数倍。16 被定义在属性 Sm4Cbc::BLOCK_LEN 内。
然后,我照做了。
(1)将【明文】字符串(比如,abcde,123
)转换成 &[u8] 数组。
(2)若 &[u8] 数组的长度不是 16 的整数倍,则将其扩容至 16 的整数倍。
(3)扩容的新数组元素,填充值为 0。我做的左侧填充。
于是,sm4 加密之。运行正常。牛!!
接着,将加密之后的新 &[u8] 做 base64 编码。发送给后端 web server。
接下来,后端先 base64 解码;再使用 crypto 库 sm4 - cbc 模式的解密 Public API 将【密文】解密为【明文】 &[u8]
最后,再使用 String::from_utf8() 将 【明文】 &[u8] 变形回【明文】 字符串。
但是,在这里我的问题来了。解密之后的明文字符串是
\u{0}\u{0}\u{0}\u{0}\u{0}\u{0}\u{0}abcde,123
我分析:上面左侧一连串的 \u{0} 是我在加密过程中,给 &[u8] 数组左填充的 0。右侧的解决结果 abcde,123 是正确的。太牛了!!!
大神,对于潜在任意长度的【明文】 字符串,我如何才能避免或解决(加密过程中)由 &[u8] 数组扩容(长度必须是 16 的整数倍)填充值 0 造成的 解密结果里的 \u{0} 呀?
大神,我不知道我在上面的描述是否清晰。但,还是请求您的帮助。下面附上我的代码:
use base64;
use crypto2::blockmode::Sm4Cbc;
use std::error::Error;
/// 加密
pub fn encrypt_cbc(text: &str, iv: &str, key: Option<String>) -> String {
let key = match key {
Some(value) => value,
None => CIPHER_IV.to_string()
};
let mut cipher = Sm4Cbc::new(key.as_bytes(), iv.as_bytes());
let cipher_text = text.as_bytes(); // 明文字符串 -> 明文 &[u8]
let original_len = cipher_text.len();
let pad_len = ((original_len as f64 / Sm4Cbc::BLOCK_LEN as f64).ceil() * 16_f64) as usize; // 计算 16 的整数倍
let mut cipher_text1: Vec<u8> = Vec::new();
for _ in original_len..pad_len {
cipher_text1.push(0);
}
cipher_text1.extend_from_slice(cipher_text); // 扩容与左侧填充 0
cipher.encrypt(&mut cipher_text1);
base64::encode(cipher_text1)
}
/// 解密
pub fn decrypt_cbc(cipher_text: &str, iv: &str, key: Option<String>) -> Result<String, Box<dyn Error>> {
let key = match key {
Some(value) => value,
None => CIPHER_IV.to_string()
};
let cipher_text = base64::decode(cipher_text)?;
let mut cipher = Sm4Cbc::new(key.as_bytes(), iv.as_bytes());
let mut cipher_text: Vec<u8> = cipher_text.iter().cloned().collect();
cipher.decrypt(&mut cipher_text);
match String::from_utf8(cipher_text) {
Ok(rs) => Ok(rs),
Err(err) => Err(Box::new(err))
}
}
大神,我想在项目里使用您这个加密库。sm4 - cbc 模式就差最后这么一点就搞定了。希望获得您的指点与帮助。
As the title.
java code
public static String AESEncrypt(String plainText, SecretKey key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
if (ObjectUtils.isEmpty(plainText)) return plainText;
Cipher aesCipher = Cipher.getInstance("AES");
aesCipher.init(Cipher.ENCRYPT_MODE, key);
return Base64.getEncoder().encodeToString(aesCipher.doFinal(plainText.getBytes()));
}
public static void main(String[] args) {
String key = "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=";
String before = "James";
try {
String after = AESEncrypt(before, new SecretKeySpec(Base64.getDecoder().decode(key), "AES"));
System.out.println(before);
System.out.println(after);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
java code ouput
James
u9QmnI+gjMUK9LETbm2eWA==
rust code
pub fn test_aes(&self, password: String, data: String) -> String {
let key = base64::decode(password).unwrap();
let cipher = Aes256::new(key.as_slice());
let mut text = data.as_bytes().clone().to_owned();
cipher.encrypt(&mut text);
return base64::encode(text);
}
pub fn test(&self) {
let password = "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=".to_string();
let data = "James".to_string();
println!("{}\n{}", data.clone(), self.test_aes(password, data));
}
rust code ouput
James
vWkOWA0=
base64("12345678901234567890123456789012") = "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI"
aes online result
Is there anything wrong with how I use it?
大神呀!
我使用由此 crypto 包交叉编译而来的 wasm - npm 依赖,从前端 sm4 - cbc 加密明文。然后,传输【密文】给后端 java web server 解密。但是,后端 java web server 不能成功解密。注意:crypto 包是能够成功解密自己加密的密文的。关于此,我写过单元测试,验证过了。
通过与后端 java web server 大牛的反复沟通(我是不会后端的小前端一枚),他们给我一个【京东数科】的在线【SM4 - 128位 - cbc】加密与解密工具。而且,java 大牛告诉我:“后端使用的 java 版本128 位 sm4 cbc加密与解密结果与【京东数科】在线工具一致”。
然后,我使用【京东数科】在线工具,加密了一段内容:
结果密文:
接着,我在咱们 crypto 包的src\blockmode\cbc.rs
文件里,添加了一个新单元测试:
#[test]
fn test_sm4_enc() { // https://aks.jd.com/tools/sec/
let key = "1234567890123456".as_bytes();
let nonce = "abcdefghijkmlnop".as_bytes();
let plain_text = "zyxwvusrqponlmkj".as_bytes(); // 十六位,不需要填充,所以是 nopadding 模式
let mut cipher = Sm4Cbc::new(&key, &nonce);
let mut cipher_text = Vec::new();
cipher_text.extend_from_slice(plain_text);
cipher.encrypt(&mut cipher_text);
let cipher_text = hex::encode(cipher_text);
assert_eq!(cipher_text, "8ea150185ca6fc6937a2014be655f01a");
}
在运行了上面的单元测试之后,我发现它们的加密结果真的不一样。咱们 crypto 包的加密结果是:b5330fcbc79100ddcc7caa8534ea66f5
最后,请 @LuoZijun 等大神们看一眼,是我在单元测试里写的调用方式不对(会不会是我直接使用.as_bytes()
是不对的?),还是咱们伟大的 crypto 包真的有缺陷。
最近ss-rust版本做了一次大升级,性能得到提高的同时,有个问题一直困扰着我。
编译系统:fedora 32
rust tool-chain:nightly-x86_64-unknown-linux-gnu (12-30)
rust编译的版本:shadowsocks/shadowsocks-rust@e048bc2
启动命令:
screen -S ss.rust -d -m -L ./ssserver --config shadowsocks.json -v -U --inbound-send-buffer-size 8192 --inbound-recv-buffer-size 8192 --outbound-send-buffer-size 8192 --outbound-recv-buffer-size 8192
运行一段时间,会导致ss服务奔溃。时间周期未测试出来,不过应该跟时间关系不大。
奔溃的日志如下:
thread 'main' panicked at 'assertion failed: aead_pkt.len() >= Self::TAG_LEN', /root/.cargo/registry/src/github.com-1ecc6299db9ec823/shadowsocks-crypto-0.1.0/src/v1/ring.rs:116:9
打开上述的ring.rs文件,定位到116行,代码如下:
#[must_use]
pub fn decrypt_slice(&self, nonce: &[u8], aad: &[u8], aead_pkt: &mut [u8]) -> bool {
assert_eq!(nonce.len(), Self::NONCE_LEN);
assert!(aead_pkt.len() >= Self::TAG_LEN);
let clen = aead_pkt.len() - Self::TAG_LEN;
let nonce = Nonce::try_assume_unique_for_key(nonce).unwrap();
let aad = Aad::from(aad);
match self.cipher.open_in_place(nonce, aad, aead_pkt) {
Ok(plaintext) => {
assert_eq!(plaintext.len(), clen);
true
},
Err(_) => {
false
}
}
}
从逻辑来看没什么毛病,不知如何入手解决,麻烦替我看看怎么处理。
Boss, after the Rustc upgrade (Rustc 1.81.0 slightly (d8a38b000 2024-06-19)), there are two features that cannot be used: stdsimd and llvm-asm
error: range is out of bounds
--> src/blockmode/gcm_siv.rs:114:28
|
21 | / macro_rules! impl_block_cipher_with_gcm_siv_mode {
22 | | ($name:tt, $cipher:tt) => {
23 | |
24 | | #[derive(Clone)]
... |
114 | | ek[16..24].copy_from_slice(&tmp[0..8]);
| | ^^
... |
283 | | }
284 | | }
| |_- in this expansion of `impl_block_cipher_with_gcm_siv_mode!`
285 |
286 | impl_block_cipher_with_gcm_siv_mode!(Aes128GcmSiv, Aes128);
| ----------------------------------------------------------- in this macro invocation
|
= note: requested on the command line with `-D clippy::out-of-bounds-indexing`
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#out_of_bounds_indexing
error: range is out of bounds
--> src/blockmode/gcm_siv.rs:119:24
|
21 | / macro_rules! impl_block_cipher_with_gcm_siv_mode {
22 | | ($name:tt, $cipher:tt) => {
23 | |
24 | | #[derive(Clone)]
... |
119 | | ek[24..32].copy_from_slice(&tmp[0..8]);
| | ^^
... |
283 | | }
284 | | }
| |_- in this expansion of `impl_block_cipher_with_gcm_siv_mode!`
285 |
286 | impl_block_cipher_with_gcm_siv_mode!(Aes128GcmSiv, Aes128);
| ----------------------------------------------------------- in this macro invocation
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#out_of_bounds_indexing
error: range is out of bounds
--> src/blockmode/gcm_siv.rs:114:28
|
21 | / macro_rules! impl_block_cipher_with_gcm_siv_mode {
22 | | ($name:tt, $cipher:tt) => {
23 | |
24 | | #[derive(Clone)]
... |
114 | | ek[16..24].copy_from_slice(&tmp[0..8]);
| | ^^
... |
283 | | }
284 | | }
| |_- in this expansion of `impl_block_cipher_with_gcm_siv_mode!`
...
289 | impl_block_cipher_with_gcm_siv_mode!(Sm4GcmSiv, Sm4);
| ----------------------------------------------------- in this macro invocation
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#out_of_bounds_indexing
error: range is out of bounds
--> src/blockmode/gcm_siv.rs:119:24
|
21 | / macro_rules! impl_block_cipher_with_gcm_siv_mode {
22 | | ($name:tt, $cipher:tt) => {
23 | |
24 | | #[derive(Clone)]
... |
119 | | ek[24..32].copy_from_slice(&tmp[0..8]);
| | ^^
... |
283 | | }
284 | | }
| |_- in this expansion of `impl_block_cipher_with_gcm_siv_mode!`
...
289 | impl_block_cipher_with_gcm_siv_mode!(Sm4GcmSiv, Sm4);
| ----------------------------------------------------- in this macro invocation
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#out_of_bounds_indexing
error: range is out of bounds
--> src/blockmode/gcm_siv.rs:114:28
|
21 | / macro_rules! impl_block_cipher_with_gcm_siv_mode {
22 | | ($name:tt, $cipher:tt) => {
23 | |
24 | | #[derive(Clone)]
... |
114 | | ek[16..24].copy_from_slice(&tmp[0..8]);
| | ^^
... |
283 | | }
284 | | }
| |_- in this expansion of `impl_block_cipher_with_gcm_siv_mode!`
...
290 | impl_block_cipher_with_gcm_siv_mode!(Camellia128GcmSiv, Camellia128);
| --------------------------------------------------------------------- in this macro invocation
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#out_of_bounds_indexing
error: range is out of bounds
--> src/blockmode/gcm_siv.rs:119:24
|
21 | / macro_rules! impl_block_cipher_with_gcm_siv_mode {
22 | | ($name:tt, $cipher:tt) => {
23 | |
24 | | #[derive(Clone)]
... |
119 | | ek[24..32].copy_from_slice(&tmp[0..8]);
| | ^^
... |
283 | | }
284 | | }
| |_- in this expansion of `impl_block_cipher_with_gcm_siv_mode!`
...
290 | impl_block_cipher_with_gcm_siv_mode!(Camellia128GcmSiv, Camellia128);
| --------------------------------------------------------------------- in this macro invocation
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#out_of_bounds_indexing
error: range is out of bounds
--> src/blockmode/gcm_siv.rs:114:28
|
21 | / macro_rules! impl_block_cipher_with_gcm_siv_mode {
22 | | ($name:tt, $cipher:tt) => {
23 | |
24 | | #[derive(Clone)]
... |
114 | | ek[16..24].copy_from_slice(&tmp[0..8]);
| | ^^
... |
283 | | }
284 | | }
| |_- in this expansion of `impl_block_cipher_with_gcm_siv_mode!`
...
292 | impl_block_cipher_with_gcm_siv_mode!(Aria128GcmSiv, Aria128);
| ------------------------------------------------------------- in this macro invocation
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#out_of_bounds_indexing
error: range is out of bounds
--> src/blockmode/gcm_siv.rs:119:24
|
21 | / macro_rules! impl_block_cipher_with_gcm_siv_mode {
22 | | ($name:tt, $cipher:tt) => {
23 | |
24 | | #[derive(Clone)]
... |
119 | | ek[24..32].copy_from_slice(&tmp[0..8]);
| | ^^
... |
283 | | }
284 | | }
| |_- in this expansion of `impl_block_cipher_with_gcm_siv_mode!`
...
292 | impl_block_cipher_with_gcm_siv_mode!(Aria128GcmSiv, Aria128);
| ------------------------------------------------------------- in this macro invocation
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#out_of_bounds_indexing
error: aborting due to 8 previous errors
在android下编译发生异常:
> Task :core:cargoBuildArm64
Compiling crypto2 v0.1.2
Compiling serde-value v0.7.0
Compiling mio v0.7.11
Compiling json5 v0.3.0
error[E0425]: cannot find function `vmull_p64` in this scope
--> .cargo/registry/src/github.com-1ecc6299db9ec823/crypto2-0.1.2/src/mac/ghash/./aarch64.rs:16:15
|
16 | transmute(vmull_p64(a, b))
| ^^^^^^^^^ help: a function with a similar name exists: `vmul_f64`
|
::: .rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/../../stdarch/crates/core_arch/src/aarch64/neon/generated.rs:4477:1
|
4477 | pub unsafe fn vmul_f64(a: float64x1_t, b: float64x1_t) -> float64x1_t {
| --------------------------------------------------------------------- similarly named function `vmul_f64` defined here
…………
Compiling log4rs v1.0.0
Compiling tokio v1.5.0
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0425`.
error: could not compile `crypto2`
The i386 build seems to have problems with illegal instructions.
I guess it's related to crypto2: https://github.com/shadowsocks/crypto2/blob/master/src/blockcipher/aes/x86.rs#L13
For some old x86 devices without AES instructions, we may need to disable the ASM here.
To simplify the logic, we can totally disable assembly acceleration on armeabi and i386 build.
/data/user_de/0/com.github.shadowsocks/no_backup/stat_main -c /data/user/0/com.github.shadowsocks/no_backup/shadowsocks.conf --vpn -U --dns-addr 127.0.0.1:5450 --remote-dns-addr dns.google:53 --acl /data/user_de/0/com.github.shadowsocks/no_backup/bypass-lan.acl
12-11 16:58:39.620 11047 11047 F libc : Fatal signal 4 (SIGILL), code 2 (ILL_ILLOPN), fault addr 0x5f62c2e7 in tid 11047 (libsslocal.so), pid 11047 (libsslocal.so)
12-11 16:58:39.657 11053 11053 I crash_dump32: obtaining output fd from tombstoned, type: kDebuggerdTombstone
12-11 16:58:39.660 1873 1873 I /system/bin/tombstoned: received crash request for pid 11047
12-11 16:58:39.672 11053 11053 I crash_dump32: performing dump of process 11047 (target tid = 11047)
12-11 16:58:39.672 11053 11053 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
12-11 16:58:39.672 11053 11053 F DEBUG : Build fingerprint: 'google/sdk_gphone_x86/generic_x86:10/QSR1.190920.001/5891938:user/release-keys'
12-11 16:58:39.672 11053 11053 F DEBUG : Revision: '0'
12-11 16:58:39.672 11053 11053 F DEBUG : ABI: 'x86'
12-11 16:58:39.672 11053 11053 F DEBUG : Timestamp: 2020-12-11 16:58:39+0800
12-11 16:58:39.673 11053 11053 F DEBUG : pid: 11047, tid: 11047, name: libsslocal.so >>> /data/app/com.github.shadowsocks-aP4h93XpVwl34bjFzFASdQ==/lib/x86/libsslocal.so <<<
12-11 16:58:39.673 11053 11053 F DEBUG : uid: 10134
12-11 16:58:39.673 11053 11053 F DEBUG : signal 4 (SIGILL), code 2 (ILL_ILLOPN), fault addr 0x5f62c2e7 (*pc=0x8328f8c5)
12-11 16:58:39.673 11053 11053 F DEBUG : eax ffb366f4 ebx 5f9abe24 ecx ef469068 edx 00000000
12-11 16:58:39.673 11053 11053 F DEBUG : edi ffb366f4 esi 0000000d
12-11 16:58:39.673 11053 11053 F DEBUG : ebp ffb366f4 esp ffb36630 eip 5f62c2e7
12-11 16:58:39.685 11053 11053 F DEBUG :
12-11 16:58:39.685 11053 11053 F DEBUG : backtrace:
12-11 16:58:39.685 11053 11053 F DEBUG : #00 pc 000cb2e7 /data/app/com.github.shadowsocks-aP4h93XpVwl34bjFzFASdQ==/lib/x86/libsslocal.so
12-11 16:58:39.685 11053 11053 F DEBUG : #01 pc 000898e8 /apex/com.android.runtime/lib/bionic/libc.so (__libc_init+120) (BuildId: 76290498408016ad14f4b98c3ab6c65c)
Originally posted by @madeye in shadowsocks/shadowsocks-android#2622 (comment)
The fastest cryptographic library in the galaxy
Proof?
I‘ve already install nightly toolchain, just like :
Default host: x86_64-apple-darwin
rustup home: /Users/limodou/.rustup
installed toolchains
--------------------
stable-x86_64-apple-darwin
beta-x86_64-apple-darwin
nightly-x86_64-apple-darwin (default)
1.56.0-x86_64-apple-darwin
installed targets for active toolchain
--------------------------------------
wasm32-unknown-unknown
x86_64-apple-darwin
active toolchain
----------------
nightly-x86_64-apple-darwin (default)
rustc 1.60.0-nightly (8cdb3cd94 2022-01-25)
So how to fixed the error? Thanks.
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.