A Rust Library of China's Standards of Encryption Algorithms (SM2/3/4)

Overview

Libsm

Libsm is an open source pure rust library of China Cryptographic Algorithm Standards. It is completed by a collaborative effort between the Cryptape Technology LLC. and BEIHANG KNOC LAB. And now this project is maintained by Cryptape Technology LLC.

GM/T Algorithms

Libsm implements the following GM/T cryptographic algorithms:

  • SM2 (GM/T 0003-2012): elliptic curve cryptographic schemes including digital signature scheme, public key encryption, (authenticated) key exchange protocol and one recommended 256-bit prime field curve sm2p256v1.
  • SM3 (GM/T 0004-2012): cryptographic hash function with 256-bit digest length.
  • SM4 (GM/T 0002-2012): block cipher with 128-bit key length and 128-bit block size, also named SMS4.

Documents

License

Libsm is currently under the Apache 2.0 license.

Comments
  • use w_naf to reduce time consume of point_mul

    use w_naf to reduce time consume of point_mul

    w-naf can effectively reduce the time consumption of point multiplication. In sm2, we set the width of the window to 5, and the except time consumption is 50A+257D where the origin time consumption is 128A+256D.

    opened by FullyRobert 17
  • ecc曲线point add 和point double 计算结果不同

    ecc曲线point add 和point double 计算结果不同

    我尝试为sm2算法中的ecc.rs代码内,为测试test_add_double_neg增加以下测试,该测试希望验证点加法和点倍增的结果是否相同:

            let double_g = curve.double(&g);  //  2 * g
            let add_g = curve.add(&g,&g);     // g + g
            assert!(curve.eq(&add_g,&double_g));
    

    但是测试结果告诉我没有通过测试:

    thread 'sm2::ecc::tests::test_add_double_neg' panicked at 'assertion failed: curve.eq(&add_g, &double_g)', src\sm2\ecc.rs:595:
    

    ~~查看了一下实现点加法和点倍增的算法,发现算法和我之前学习的算法有所出入。例如,点倍增算法中引入了参数a:~~ ~~而论文中实现点倍增并没有参数a的参与(雅可比坐标系下)~~ 经过学习,了解到此处点倍增利用的似乎是dbl-1998-cmo-2中的方法,抱歉。点加法似乎是使用了add-2007-bl中的算法?

    想请问点加法和点倍增计算结果为何不一致的原因,以及计算点加法和点乘法时使用到的算法名称。个人水平有限,难免在理解上会出现错误,烦请多多指教

    opened by FullyRobert 6
  • use 1998-cmo-2 algorithm to improve speed of point add and point double

    use 1998-cmo-2 algorithm to improve speed of point add and point double

    The point add(PA) and point double(PD) algorithms in libsm are named add-1998-cmo and double-1998-cmo. The time consume of these algorithmS are 10M + 5S + 4cubic = 23M and 3M + 3S + 2^4 = 12M . According to website https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-add-1998-cmo-2, the fastest PA and PD named add-1998-cmo-2 and double-1998-cmo-2 only need 16M and 9M.

    After replacing new algorithms, the time consume of PA and PD decreased by 35% and 15% respectively. I use criterion to compare the speed before and after the improvement. It must be noted that the optimization efficiency will be different when PA and PD calculate different points

    PA:

    Ecc add time: [1.3219 us 1.3611 us 1.4074 us]
    change: [-47.407% -45.710% -43.853%] (p = 0.00 < 0.05) Performance has improved.

    Test code:

    fn ecc_add(c: &mut Criterion) {
        let curve = EccCtx::new();
        let g = curve.generator();
        let neg_g = curve.neg(&g);
        let double_g = curve.double(&g);
        c.bench_function("Ecc old add ", move |b| {
            b.iter(|| curve.add(&double_g, &neg_g));
        });
    }
    

    PD:

    Ecc double time: [1.1666 us 1.1969 us 1.2322 us]
    change: [-19.976% -18.640% -16.936%] (p = 0.00 < 0.05) Performance has improved.

    Test code:

    fn ecc_double(c: &mut Criterion) {
        let curve = EccCtx::new();
        let g = curve.generator();
    
        c.bench_function("Ecc double ", move |b| {
            b.iter(|| curve.double(&g));
        });
    }
    
    opened by FullyRobert 4
  • sm2加解密时klen怎么设置?

    sm2加解密时klen怎么设置?

    https://github.com/citahub/libsm/blob/3ead619a180deb93474634584791b02561ca9a70/src/sm2/encrypt.rs#L142-L153

    如上代码示例, 加解密时 klen 为要加密码信息的长度,我尝试使用固定值(E.g. 1024)会报错。 由于加密与解密可能在不同流程中使用,加密时可以知道原始数据的长度,但解密时只有密文,无法获取到原始数据的长度。请问要如何处理?

    opened by gudaoxuri 2
  • Add Implementation of SM2 Encryption, Decryption and Key Exchange Protocol

    Add Implementation of SM2 Encryption, Decryption and Key Exchange Protocol

    The implementation of SM2 public key encryption, decryption algorithm and key exchange protocol is mainly finished here.

    Additional usage has been written in doc, in which the markdown format is also optimized for syntax highlighting in rust code.

    However, my test cases may not be exhaustive enough to cover all situations. Hope my code can be well-reviewed, and any suggestions are welcomed.

    opened by Garen-Wang 2
  • Invalid private key length, sometimes

    Invalid private key length, sometimes

    First. I created a private key and return hex.

    let ctx = SigCtx::new();
    let (pk, sk) = ctx.new_keypair();
    format!("0x{}", hex::encode(sk.to_bytes_be()))
    // 0x11a8571fe8ee79990db44379aac8d67606a783ac73f52113d563dce7f38fdf
    

    Next, the data is signed with the private key

    let ctx = SigCtx::new();
    let privk = hex::decode("0x11a8571fe8ee79990db44379aac8d67606a783ac73f52113d563dce7f38fdf")
    let sk = ctx.load_seckey(&privk).unwrap();
    // this painic. result returns Err(true)
    

    The length of a valid private key that doesn't include 0x should be 64, it's only 62.

    version: git commit 5cc6f4d251456347f17ad836a00c8248c3563cbf rust: rustc 1.31.0-nightly (8c4ad4e9e 2018-10-04)

    opened by yejiayu 2
  • Extend the precomputation table to accelerate g_mul operation

    Extend the precomputation table to accelerate g_mul operation

    In the original code, the g_mul function pre-computes 512 values and then uses these values to calculate base_point multiplication, which requires 31 point additions and 16 point double.

    Inspired by #37, I think we can extend the precomputation table to accelerate g_mul operation. In the new model we have designed, the precomputed table has a total of 256*32 = 8192 items. When calculating the gmul calculation, we slice the BigUint k into 32 pieces k0-k31 and then call the precomputed table to get their multiplication with G. Finally, the 31 results are added together to obtain the final result.

    In the new model, 16 point double operations have been removed, which can improve the speed of gmul. I write a bench function to compare two functions:

    test sm2::ecc::internal_benches::bench_gmul_new ... bench: 58,823 ns/iter (+/- 9,798) test sm2::ecc::internal_benches::bench_gmul_old ... bench: 86,592 ns/iter (+/- 13,441)

    However, the ability to save precomputed results to a file is not yet available. Hope my code can be well-reviewed, and I will add more commit to implement it.

    opened by FullyRobert 1
  • Fix Sm2Error debug impl

    Fix Sm2Error debug impl

    #[cfg(test)]
    mod tests {
        use super::Sm2Error;
    
        #[test]
        fn test_debug() {
            let e = Sm2Error::InvalidPublic;
            println!("{:?}", e); // thread 'sm2::error::tests::test_debug' has overflowed its stack
        }
    }
    

    This is because {:?} will call the Debug impl itself.

    impl ::std::fmt::Debug for Sm2Error {
        fn fmt(&self, f: &mut Formatter<'_>) -> ::std::fmt::Result {
            write!(f, "{:?}", self)
        }
    }
    
    
    opened by whfuyn 1
  • how can i use encode and decode with sm2

    how can i use encode and decode with sm2

    i see the test code for encode and decode like this

    #[test]
        fn test_sig_encode_and_decode() {
            let string = String::from("abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd");
            let msg = string.as_bytes();
    
            let ctx = SigCtx::new();
            let (pk, sk) = ctx.new_keypair();
    
            let signature = ctx.sign(msg, &sk, &pk);
            let der = signature.der_encode();
            let sig = Signature::der_decode(&der[..]).unwrap();
            assert!(ctx.verify(msg, &pk, &sig));
    
            let signature = ctx.sign(msg, &sk, &pk);
            let der = signature.der_encode();
            let sig = Signature::der_decode_raw(&der[2..]).unwrap();
            assert!(ctx.verify(msg, &pk, &sig));
        }
    

    but i need a methods to encrypt plaintext.

    opened by Taoja 1
  • remove outdated method & modify bench function error

    remove outdated method & modify bench function error

    The new w-naf point_mul method has been tested and merged in #30 , so the old method can be removed now.

    Modify bench function error because of the interface change in #41 .

    opened by FullyRobert 0
  • use shr to replace div 2 for inv_n

    use shr to replace div 2 for inv_n

    For the BigUint , the shift right operation (>>) takes only 25% of the time of the division operation, and replacing the right shift operation with the division operation can effectively improve the speed of calculating the multiplication inverse. BigUInt

    opened by FullyRobert 0
  • Add description of WebAssembly support

    Add description of WebAssembly support

    You can use this crates in WebAssembly. Currently, you only need to add dependencies:

    # Cargo.toml
    getrandom = { version = "^0.2", features = ["js"] }
    

    See getrandom#WebAssembly support. But it still needs improvement for the first time #47

    opened by byeblack 0
  • load gmul table from disk

    load gmul table from disk

    pr #45 and issues #37 both mention that loading gmul_table from disk is an elegant way. In this pr, I modify the g_table function, introduced Serde crate to serialize the table, and store it in the file gmul_table. When the gmul function needs to use g_table, it can easily load the file and deserialize it as a table struct.

    Benchmark tests have found that the performance improvement of the gmul function using the load approach is not significant (about 2-5%), probably because a large number of gmul operations amortizes the precomputed gtable time. In any case, loading gtable from the hard disk is effective in reducing warming time, and the loading time is nearly zero( 300mb/s for serde deserialize procedure)

    Hope my code can be well-reviewed, and I will add more commit to implement it.

    Test result:

    test sm2::ecc::internal_benches::bench_gmul ... bench: 50,762 ns/iter (+/- 791) test sm2::ecc::internal_benches::bench_gmul_load ... bench: 48,357 ns/iter (+/- 1,143)

    opened by FullyRobert 1
  • sm2 解密时,如果密文格式不正确,会导致 panic

    sm2 解密时,如果密文格式不正确,会导致 panic

    pub fn decrypt(&self, cipher: &[u8]) -> Sm2Result<Vec<u8>> 方法

    转 c_1_point 时,如果遇到异常能否“透传”出来? 最好 let c_1_point = self.curve.bytes_to_point(c_1_bytes).unwrap(); 这里可以不要直接 unwrap(), 能把这里的异常也 return 出来。

    现在,这里面的 Sm2Error::InvalidPublic Sm2Error::NotOnCurve 等,外层好像没法处理。

    opened by samurai00 0
Releases(0.5.0)
Owner
CITAHub
CITAHub
Authenticated Encryption with Associated Data Algorithms: high-level encryption ciphers

RustCrypto: Authenticated Encryption with Associated Data (AEAD) Algorithms Collection of Authenticated Encryption with Associated Data (AEAD) algorit

Rust Crypto 457 Jan 4, 2023
Rust encryption library for practical time-lock encryption.

tlock_age: Hybrid Timelock Encryption/Decryption in Rust tlock_age is a library to encrypt and decrypt age filekey using tlock scheme. It provides an

Thibault 5 Mar 29, 2023
Chargo is a tool for file encryption/decryption. It's based on Argon2 and ChaCha20Poly1305 algorithms.

| Documentation Chargo is a tool for file encryption/decryption with password. It's based on Argon2 and ChaCha20Poly1305 algorithms. From arg2u with ♥

Airat Galiullin 7 Jan 1, 2023
Rust implementation of CAIP standards

Rust CAIP Standard Utilities Chain Agnostic Improvement Proposals (CAIP) is a set of standards for multi-chain interoperability. CAIP-2: Chain ID use

Public Awesome 6 Dec 12, 2022
rabe is an Attribute Based Encryption library, written in Rust

Rabe rabe is a rust library implementing several Attribute Based Encryption (ABE) schemes using a modified version of the bn library of zcash (type-3

Fraunhofer AISEC 52 Dec 15, 2022
A Rust library for lattice-based additive homomorphic encryption.

Cupcake Cupcake is an efficient Rust library for the (additive version of) Fan-Vercauteren homomorphic encryption scheme, offering capabilities to enc

Facebook Research 365 Dec 11, 2022
In addition to encryption library, pure RUST implementation of SSH-2.0 client protocol

In addition to encryption library, pure RUST implementation of SSH-2.0 client protocol

陈年旧事。 73 Jan 1, 2023
Rust library for practical time-lock encryption using `drand` threshold network

tlock-rs: Practical Timelock Encryption/Decryption in Rust This repo contains pure Rust implementation of drand/tlock scheme. It provides time-based e

Timofey 32 Jan 8, 2023
WebAssembly wrapper of the rage encryption library

rage-wasm: WebAssembly wrapper of rage rage is a simple, modern, and secure file encryption tool, using the age format. It features small explicit key

Kan-Ru Chen 35 Dec 16, 2022
Meta-repository for Miscreant: misuse-resistant symmetric encryption library with AES-SIV (RFC 5297) and AES-PMAC-SIV support

The best crypto you've never heard of, brought to you by Phil Rogaway A misuse resistant symmetric encryption library designed to support authenticate

miscreant. 480 Dec 8, 2022
A Rust binary for file encryption to multiple participants.

Kaspa-miner A Rust binary for file encryption to multiple participants. Installation From Sources With Rust's package manager cargo, you can install k

Elichai Turkel 31 Dec 30, 2022
A secure file encryption utility, written in rust.

Dexios Dexios What is it? Building notes Checksums Performance Output file sizes Environment Variables Key Inputs Usage Examples To Do What is it? Dex

brxken 156 Dec 22, 2022
Simple to use CLI tool that makes encryption easy! Written in Rust.

?? eme: Encryption Made Easy an extremely simple AES-256 encryption tool written in Rust Usage: # To encrypt: eme --encrypt secret.png # To decrypt: e

null 5 Jan 3, 2023
🔐 UPLINK is a Rust lightweight (2MB) tool for file transfer and remote management that uses AES-GCM and Envelope Encryption over WebSockets.

UPLINK ░▒▓█▓▒░░▒▓█▓▒░▒▓███████▓▒░░▒▓█▓▒░ ░▒▓█▓▒░▒▓███████▓▒░░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█

Krystian Bajno 5 Sep 28, 2024
End-to-end encryption and mutual authentication for distributed applications.

✨ Hands-on Introduction: Build end-to-end encrypted, mutually-authenticated, secure messaging in Rust ✨ Rust and Elixir libraries for end-to-end encry

Ockam | Trust for Data-in-Motion 2.8k Jan 2, 2023
DexiosGUI - Simple cross-platform drag-and-drop Dexios file encryption

DexiosGUI Simple cross-platform drag-and-drop Dexios file encryption. Latest Windows x64 release is here. DexiosGUI is a Qt/C++ app for encrypt and de

Fabrice Corraire 4 Jul 25, 2022
The Hybrid Public Key Encryption (HPKE) standard in Python

Hybrid PKE The Hybrid Public Key Encryption (HPKE) standard in Python. hybrid_pke = hpke-rs ➕ PyO3 This library provides Python bindings to the hpke-r

Cape Privacy 4 Nov 7, 2022
Project Masterpass is a deterministic databaseless key management algorithm, aimed to help those who cannot protect their encryption keys in storage

Project Masterpass (working title) Attention! This project is still under heavy development, and SHOULD NOT be used in practice, as the algorithms cou

Gyorgy Wang 2 Sep 11, 2022
A simple to use, cross-platform aes encryption

About Project End to End encryption (AES) for multiple languages (cross-platform) with CBC Icon Item ?? Upcoming ⚖️ License ?? ChangeLog Usage (rust)

Zot Cryptography 2 Dec 15, 2022