├── Cargo.toml ├── gm-sm2 ├── pki │ ├── public_key_pkcs8.pem │ └── private_key_pkcs8.pem ├── src │ ├── fields.rs │ ├── error.rs │ ├── fields │ │ ├── fn64.rs │ │ └── fp64.rs │ ├── pkcs.rs │ ├── u256.rs │ ├── lib.rs │ ├── util.rs │ ├── exchange.rs │ ├── key.rs │ └── p256_ecc.rs ├── Cargo.toml └── README.md ├── .gitignore ├── gm-sm3 ├── README.md ├── Cargo.toml └── src │ └── lib.rs ├── gm-zuc ├── Cargo.toml ├── README.md └── src │ ├── eea.rs │ ├── eia.rs │ └── lib.rs ├── gm-sm4 ├── README.md ├── Cargo.toml └── src │ └── lib.rs ├── README.md └── gm-sm9 ├── Cargo.toml ├── benches └── sm9.rs ├── src ├── error.rs ├── fields.rs ├── fields │ ├── fp4.rs │ ├── fp.rs │ ├── fp2.rs │ └── fp12.rs ├── u256.rs └── lib.rs └── README.md /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "gm-sm2", 4 | "gm-sm3", 5 | "gm-sm4", 6 | "gm-zuc", 7 | "gm-sm9", 8 | ] 9 | resolver = "2" -------------------------------------------------------------------------------- /gm-sm2/pki/public_key_pkcs8.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEnyD93SKI7sPVZpljbFFNK4euvHIj 3 | FWcBfxLVSrQKngsIGRHFeBQ9SEHIVTmjohuPVWSXaMoviLVoZFt4JTXI8Q== 4 | -----END PUBLIC KEY----- -------------------------------------------------------------------------------- /gm-sm2/pki/private_key_pkcs8.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgoUY9zHeQ7DPB62Uj 3 | 1P2G9piBQM3S3Hc1jkeRc61ocNehRANCAASfIP3dIojuw9VmmWNsUU0rh668ciMV 4 | ZwF/EtVKtAqeCwgZEcV4FD1IQchVOaOiG49VZJdoyi+ItWhkW3glNcjx 5 | -----END PRIVATE KEY----- -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 6 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 7 | Cargo.lock 8 | 9 | # These are backup files generated by rustfmt 10 | **/*.rs.bk 11 | 12 | .idea 13 | target/ -------------------------------------------------------------------------------- /gm-sm3/README.md: -------------------------------------------------------------------------------- 1 | # gm-sm3 2 | 3 | A Pure Rust High-Performance Implementation of China's Standards of Encryption Algorithms SM3 4 | 5 | 6 | 7 | ## Example 8 | 9 | ```rust 10 | use gm_sm3::sm3_hash; 11 | 12 | fn main() { 13 | let hash = sm3_hash(b"abc"); 14 | let r = hex::encode(hash); 15 | assert_eq!("66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0", r); 16 | } 17 | 18 | ``` 19 | -------------------------------------------------------------------------------- /gm-zuc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "gm-zuc" 3 | version = "0.10.1" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | description = "A Rust Implementation of China's Standards of Encryption Algorithms ZUC" 8 | authors = ["evanyang1120@163.com"] 9 | homepage = "https://github.com/CrayfishGo/gm-rs.git" 10 | license = "MIT" 11 | keywords = ["ZUC"] 12 | categories = ["cryptography"] 13 | readme = "README.md" 14 | documentation = "https://docs.rs/gm-zuc/" 15 | 16 | -------------------------------------------------------------------------------- /gm-sm4/README.md: -------------------------------------------------------------------------------- 1 | # gm-sm4 2 | 3 | A Pure Rust High-Performance Implementation of China's Standards of Encryption Algorithms SM4 4 | 5 | 6 | ## Example 7 | 8 | ```rust 9 | use gm_sm4::Sm4Cipher; 10 | use hex_literal::hex; 11 | 12 | fn main() { 13 | let key = hex!("0123456789abcdeffedcba9876543210"); 14 | let plaintext = key.clone(); 15 | let ciphertext = hex!("681edf34d206965e86b3e94f536e4246"); 16 | 17 | let cipher = Sm4Cipher::new(&key).unwrap(); 18 | 19 | let enc = cipher.encrypt(&plaintext).unwrap(); 20 | assert_eq!(&ciphertext, enc.as_slice()); 21 | } 22 | 23 | ``` 24 | -------------------------------------------------------------------------------- /gm-sm3/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "gm-sm3" 3 | version = "0.10.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | description = "A Rust Implementation of China's Standards of Encryption Algorithms SM3" 8 | authors = ["evanyang1120@163.com"] 9 | homepage = "https://github.com/CrayfishGo/gm-rs.git" 10 | license = "MIT" 11 | keywords = ["sm3"] 12 | categories = ["cryptography"] 13 | readme = "README.md" 14 | documentation = "https://docs.rs/gm-sm3/" 15 | 16 | [dependencies] 17 | const-oid = "0.9" 18 | 19 | [dev-dependencies] 20 | hex = "0.4.0" 21 | -------------------------------------------------------------------------------- /gm-sm4/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "gm-sm4" 3 | version = "0.10.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | description = "A Rust Implementation of China's Standards of Encryption Algorithms SM4" 8 | authors = ["evanyang1120@163.com"] 9 | homepage = "https://github.com/CrayfishGo/gm-rs.git" 10 | license = "MIT" 11 | keywords = ["sm4"] 12 | categories = ["cryptography"] 13 | readme = "README.md" 14 | documentation = "https://docs.rs/gm-sm4/" 15 | 16 | [dependencies] 17 | hex = "0.4" 18 | const-oid = "0.9" 19 | 20 | [dev-dependencies] 21 | criterion = "0.4" 22 | hex-literal = "0.3" -------------------------------------------------------------------------------- /gm-sm2/src/fields.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::Debug; 2 | 3 | pub mod fn64; 4 | pub mod fp64; 5 | 6 | pub trait FieldModOperation: Sized + Copy + Clone + PartialEq + Eq + Debug { 7 | fn zero() -> Self; 8 | fn one() -> Self; 9 | fn is_zero(&self) -> bool; 10 | fn fp_sqr(&self) -> Self; 11 | fn fp_double(&self) -> Self; 12 | fn fp_triple(&self) -> Self; 13 | fn fp_add(&self, rhs: &Self) -> Self; 14 | fn fp_sub(&self, rhs: &Self) -> Self; 15 | fn fp_mul(&self, rhs: &Self) -> Self; 16 | fn fp_neg(&self) -> Self; 17 | fn fp_div2(&self) -> Self; 18 | fn fp_inv(&self) -> Self; 19 | fn to_byte_be(&self) -> Vec; 20 | fn from_byte_be(input: &[u8]) -> Self; 21 | } 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gm-rs 2 | 3 | ![Apache2/MIT licensed][license-image] 4 | 5 | A Pure Rust High-Performance Implementation of China's Standards of Encryption Algorithms SM2/SM3/SM4/ZUC 6 | 7 | ## License 8 | 9 | All crates licensed under either of 10 | 11 | * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) 12 | * [MIT license](http://opensource.org/licenses/MIT) 13 | 14 | at your option. 15 | 16 | ## Contribution 17 | 18 | Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as 19 | defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. 20 | 21 | [//]: # (badges) 22 | 23 | [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg 24 | 25 | 26 | 27 | ## Reference 28 | [GmSSL](https://github.com/guanzhi/GmSSL) 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /gm-sm2/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "gm-sm2" 3 | version = "0.13.0" 4 | edition = "2021" 5 | 6 | description = "A Rust Implementation of China's Standards of Encryption Algorithms SM2" 7 | authors = ["evanyang1120@163.com"] 8 | homepage = "https://github.com/CrayfishGo/gm-rs.git" 9 | license = "MIT" 10 | keywords = ["sm2"] 11 | categories = ["cryptography"] 12 | readme = "README.md" 13 | documentation = "https://docs.rs/gm-sm2/" 14 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 15 | 16 | [dependencies] 17 | byteorder = "1.0.0" 18 | rand = "0.8.4" 19 | hex = "0.4" 20 | num-traits = "0.2.14" 21 | gm-sm3 = { version = "0.10.0", path = "../gm-sm3" } 22 | num-bigint = "0.4.4" 23 | yasna = { version = "0.5.2", features = ["num-bigint"] } 24 | 25 | 26 | [dev-dependencies] 27 | criterion = "0.4" 28 | hex-literal = "0.3" 29 | 30 | [dependencies.pkcs8] 31 | version = "0.10.2" 32 | features = ["alloc", "pem"] 33 | default-features = false 34 | 35 | [dependencies.sec1] 36 | version = "0.7.3" 37 | features = [ 38 | "subtle", 39 | "zeroize", 40 | ] 41 | optional = true 42 | 43 | 44 | [features] 45 | default = ["sec1"] 46 | 47 | -------------------------------------------------------------------------------- /gm-sm9/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "gm-sm9" 3 | version = "0.3.0" 4 | edition = "2021" 5 | 6 | description = "A Rust Implementation of China's Standards of Encryption Algorithms SM9" 7 | authors = ["evanyang1120@163.com"] 8 | homepage = "https://github.com/CrayfishGo/gm-rs.git" 9 | license = "MIT" 10 | keywords = ["sm9", "IBC"] 11 | categories = ["cryptography"] 12 | readme = "README.md" 13 | documentation = "https://docs.rs/gm-sm9/" 14 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 15 | 16 | [dependencies] 17 | byteorder = "1.0.0" 18 | rand = "0.8.4" 19 | hex = "0.4" 20 | gm-sm3 = { version = "0.10.0", path = "../gm-sm3" } 21 | num-bigint = "0.4.4" 22 | 23 | [dev-dependencies] 24 | criterion = "0.4" 25 | hex-literal = "0.3" 26 | 27 | 28 | [[bench]] 29 | name = "sm9" 30 | harness = false 31 | 32 | 33 | [dependencies.pkcs8] 34 | version = "0.10.2" 35 | features = ["alloc", "pem"] 36 | default-features = false 37 | 38 | [dependencies.sec1] 39 | version = "0.7.3" 40 | features = [ 41 | "subtle", 42 | "zeroize", 43 | ] 44 | optional = true 45 | 46 | 47 | [features] 48 | default = ["sec1"] -------------------------------------------------------------------------------- /gm-sm9/benches/sm9.rs: -------------------------------------------------------------------------------- 1 | use criterion::{Criterion, criterion_group, criterion_main}; 2 | 3 | use gm_sm9::fields::FieldElement; 4 | use gm_sm9::fields::fp::{fp_from_mont, mont_mul, fp_to_mont}; 5 | 6 | fn bench_mod_add(c: &mut Criterion) { 7 | let mut group = c.benchmark_group("sm9"); 8 | let a: [u64; 4] = [ 9 | 0x54806C11D8806141, 10 | 0xF1DD2C190F5E93C4, 11 | 0x597B6027B441A01F, 12 | 0x85AEF3D078640C98, 13 | ]; 14 | 15 | let b: [u64; 4] = [ 16 | 0x0E75C05FB4E3216D, 17 | 0x1006E85F5CDFF073, 18 | 0x1A7CE027B7A46F74, 19 | 0x41E00A53DDA532DA, 20 | ]; 21 | group.bench_function("bench_mod_add", |x| x.iter(|| a.fp_add(&b))); 22 | group.finish(); 23 | } 24 | 25 | fn bench_mod_sub(c: &mut Criterion) { 26 | let mut group = c.benchmark_group("sm9"); 27 | let a: [u64; 4] = [ 28 | 0x54806C11D8806141, 29 | 0xF1DD2C190F5E93C4, 30 | 0x597B6027B441A01F, 31 | 0x85AEF3D078640C98, 32 | ]; 33 | 34 | let b: [u64; 4] = [ 35 | 0x0E75C05FB4E3216D, 36 | 0x1006E85F5CDFF073, 37 | 0x1A7CE027B7A46F74, 38 | 0x41E00A53DDA532DA, 39 | ]; 40 | group.bench_function("bench_mod_sub", |x| x.iter(|| a.fp_sub(&b))); 41 | group.finish(); 42 | } 43 | 44 | fn bench_mod_mul(c: &mut Criterion) { 45 | let mut group = c.benchmark_group("sm9"); 46 | let mut a: [u64; 4] = [ 47 | 0x54806C11D8806141, 48 | 0xF1DD2C190F5E93C4, 49 | 0x597B6027B441A01F, 50 | 0x85AEF3D078640C98, 51 | ]; 52 | group.bench_function("bench_mod_mul", |x| x.iter(|| { 53 | a = mont_mul(&a, &a) 54 | })); 55 | group.finish(); 56 | } 57 | 58 | fn bench_mod_inv(c: &mut Criterion) { 59 | let mut group = c.benchmark_group("sm9"); 60 | let a: [u64; 4] = [ 61 | 0x54806C11D8806141, 62 | 0xF1DD2C190F5E93C4, 63 | 0x597B6027B441A01F, 64 | 0x85AEF3D078640C98, 65 | ]; 66 | group.bench_function("bench_mod_inv", |x| x.iter(|| a.fp_inv())); 67 | group.finish(); 68 | } 69 | 70 | criterion_group!( 71 | benches, 72 | bench_mod_add, 73 | bench_mod_sub, 74 | bench_mod_mul, 75 | bench_mod_inv, 76 | ); 77 | criterion_main!(benches); 78 | -------------------------------------------------------------------------------- /gm-zuc/README.md: -------------------------------------------------------------------------------- 1 | # gm-zuc 2 | 3 | A Pure Rust High-Performance Implementation of China's Standards of Encryption Algorithms ZUC 4 | 5 | 6 | ## Example 7 | 8 | ```rust 9 | use gm_zuc::ZUC; 10 | 11 | fn main() { 12 | let key = [0u8; 16]; 13 | let iv = [0u8; 16]; 14 | let mut zuc = ZUC::new(&key, &iv); 15 | let rs = zuc.generate_keystream(2); 16 | for z in rs { 17 | println!("{:x}", z) 18 | } 19 | } 20 | 21 | ``` 22 | 23 | ### 128-EEA3 24 | ```rust 25 | use crate::eea::EEA; 26 | fn main(){ 27 | let ck: [u8; 16] = [ 28 | 0x17, 0x3d, 0x14, 0xba, 0x50, 0x03, 0x73, 0x1d, 0x7a, 0x60, 0x04, 0x94, 0x70, 0xf0, 29 | 0x0a, 0x29, 30 | ]; 31 | 32 | let count = 0x66035492_u32; 33 | let bearer = 0xf_u32; 34 | let direction = 0_u32; 35 | let length = 0xc1_u32; 36 | 37 | let ibs: [u32; 7] = [ 38 | 0x6cf65340, 0x735552ab, 0x0c9752fa, 0x6f9025fe, 0x0bd675d9, 0x005875b2, 0x00000000, 39 | ]; 40 | 41 | let obs: [u32; 7] = [ 42 | 0xa6c85fc6, 0x6afb8533, 0xaafc2518, 0xdfe78494, 0x0ee1e4b0, 0x30238cc8, 0x00000000, 43 | ]; 44 | 45 | // encrypt 46 | let mut eea = EEA::new(&ck, count, bearer, direction); 47 | let rs = eea.encrypt(&ibs, length); 48 | assert_eq!(obs, rs.as_slice()); 49 | 50 | // decrypt 51 | let mut eea = EEA::new(&ck, count, bearer, direction); 52 | let rs = eea.encrypt(&rs, length); 53 | assert_eq!(ibs, rs.as_slice()); 54 | } 55 | 56 | ``` 57 | 58 | ### 128-EIA3 59 | ```rust 60 | use crate::eia::EIA; 61 | fn main(){ 62 | let ik: [u8; 16] = [ 63 | 0xc9, 0xe6, 0xce, 0xc4, 0x60, 0x7c, 0x72, 0xdb, 0x00, 0x0a, 0xef, 0xa8, 0x83, 0x85, 64 | 0xab, 0x0a, 65 | ]; 66 | 67 | let count = 0xa94059da_u32; 68 | let bearer = 0x0a_u32; 69 | let direction = 0x01_u32; 70 | let length = 0x0241_u32; 71 | 72 | let m: [u32; 19] = [ 73 | 0x983b41d4, 0x7d780c9e, 0x1ad11d7e, 0xb70391b1, 0xde0b35da, 0x2dc62f83, 0xe7b78d63, 74 | 0x06ca0ea0, 0x7e941b7b, 0xe91348f9, 0xfcb170e2, 0x217fecd9, 0x7f9f68ad, 0xb16e5d7d, 75 | 0x21e569d2, 0x80ed775c, 0xebde3f40, 0x93c53881, 0x00000000, 76 | ]; 77 | 78 | let mac = 0xfae8ff0b_u32; 79 | 80 | let mut eia = EIA::new(&ik, count, bearer, direction); 81 | let rs = eia.gen_mac(&m, length); 82 | assert_eq!(mac, rs); 83 | } 84 | 85 | ``` 86 | -------------------------------------------------------------------------------- /gm-zuc/src/eea.rs: -------------------------------------------------------------------------------- 1 | use crate::ZUC; 2 | 3 | #[derive(Debug)] 4 | pub struct EEA { 5 | zuc: ZUC, 6 | } 7 | 8 | impl EEA { 9 | pub fn new(ck: &[u8], count: u32, bearer: u32, direction: u32) -> EEA { 10 | let mut iv = [0u8; 16]; 11 | 12 | iv[0] = (count >> 24) as u8; 13 | iv[1] = (count >> 16) as u8; 14 | iv[2] = (count >> 8) as u8; 15 | iv[3] = count as u8; 16 | iv[4] = (((bearer << 1) | (direction & 1)) << 2) as u8; 17 | 18 | iv[8] = iv[0]; 19 | iv[9] = iv[1]; 20 | iv[10] = iv[2]; 21 | iv[11] = iv[3]; 22 | iv[12] = iv[4]; 23 | let zuc = ZUC::new(ck, &iv); 24 | EEA { zuc } 25 | } 26 | 27 | pub fn encrypt(&mut self, msg: &[u32], ilen: u32) -> Vec { 28 | let mut rs = vec![]; 29 | let keylength = (ilen + 31) / 32; 30 | let keys = self.zuc.generate_keystream(keylength as usize); 31 | let keys = keys.as_slice(); 32 | for i in 0..keylength as usize { 33 | rs.push(msg[i] ^ keys[i]); 34 | } 35 | 36 | if ilen % 32 != 0 { 37 | rs[keylength as usize - 1] &= 0xffffffff << (32 - (ilen % 32)); 38 | } 39 | 40 | rs 41 | } 42 | } 43 | 44 | #[cfg(test)] 45 | mod eea_test { 46 | use crate::eea::EEA; 47 | 48 | #[test] 49 | fn test_eea() { 50 | let ck: [u8; 16] = [ 51 | 0x17, 0x3d, 0x14, 0xba, 0x50, 0x03, 0x73, 0x1d, 0x7a, 0x60, 0x04, 0x94, 0x70, 0xf0, 52 | 0x0a, 0x29, 53 | ]; 54 | 55 | let count = 0x66035492_u32; 56 | let bearer = 0xf_u32; 57 | let direction = 0_u32; 58 | let length = 0xc1_u32; 59 | 60 | let ibs: [u32; 7] = [ 61 | 0x6cf65340, 0x735552ab, 0x0c9752fa, 0x6f9025fe, 0x0bd675d9, 0x005875b2, 0x00000000, 62 | ]; 63 | 64 | let obs: [u32; 7] = [ 65 | 0xa6c85fc6, 0x6afb8533, 0xaafc2518, 0xdfe78494, 0x0ee1e4b0, 0x30238cc8, 0x00000000, 66 | ]; 67 | 68 | // encrypt 69 | let mut eea = EEA::new(&ck, count, bearer, direction); 70 | let rs = eea.encrypt(&ibs, length); 71 | assert_eq!(obs, rs.as_slice()); 72 | 73 | // decrypt 74 | let mut eea = EEA::new(&ck, count, bearer, direction); 75 | let rs = eea.encrypt(&rs, length); 76 | assert_eq!(ibs, rs.as_slice()); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /gm-zuc/src/eia.rs: -------------------------------------------------------------------------------- 1 | use crate::ZUC; 2 | 3 | #[derive(Debug)] 4 | pub struct EIA { 5 | zuc: ZUC, 6 | } 7 | 8 | impl EIA { 9 | pub fn new(ik: &[u8], count: u32, bearer: u32, direction: u32) -> EIA { 10 | let mut iv = [0u8; 16]; 11 | iv[0] = (count >> 24) as u8; 12 | iv[1] = (count >> 16) as u8; 13 | iv[2] = (count >> 8) as u8; 14 | iv[3] = count as u8; 15 | iv[4] = (bearer << 3) as u8; 16 | 17 | iv[8] = iv[0] ^ ((direction << 7) as u8); 18 | iv[9] = iv[1]; 19 | iv[10] = iv[2]; 20 | iv[11] = iv[3]; 21 | iv[12] = iv[4]; 22 | iv[14] = iv[6] ^ ((direction << 7) as u8); 23 | EIA { 24 | zuc: ZUC::new(ik, &iv), 25 | } 26 | } 27 | 28 | /// Return MAC 29 | pub fn gen_mac(&mut self, m: &[u32], ilen: u32) -> u32 { 30 | let keylength = (ilen + 31) / 32 + 2; 31 | let keys = self.zuc.generate_keystream(keylength as usize); 32 | let keys = keys.as_slice(); 33 | let mut t = 0_u32; 34 | for i in 0..ilen as usize { 35 | if m[i >> 5] & (0x1 << (31 - (i & 0x1f))) > 0 { 36 | t ^= find_word(keys, i); 37 | } 38 | } 39 | 40 | t ^= find_word(keys, ilen as usize); 41 | t ^ find_word(keys, 32 * (keylength - 1) as usize) 42 | } 43 | } 44 | 45 | /// Return 46 | /// ```txt 47 | /// K_i = K[i] || K[i+1] || ... || K[i+31] 48 | /// ``` 49 | fn find_word(keys: &[u32], i: usize) -> u32 { 50 | let j = i >> 5; 51 | let m = i & 0x1f; 52 | if m == 0 { 53 | keys[j] 54 | } else { 55 | (keys[j] << m) | (keys[j + 1] >> (32 - m)) 56 | } 57 | } 58 | 59 | #[cfg(test)] 60 | mod eia_test { 61 | use crate::eia::EIA; 62 | 63 | #[test] 64 | pub fn test_eia() { 65 | let ik: [u8; 16] = [ 66 | 0xc9, 0xe6, 0xce, 0xc4, 0x60, 0x7c, 0x72, 0xdb, 0x00, 0x0a, 0xef, 0xa8, 0x83, 0x85, 67 | 0xab, 0x0a, 68 | ]; 69 | 70 | let count = 0xa94059da_u32; 71 | let bearer = 0x0a_u32; 72 | let direction = 0x01_u32; 73 | let length = 0x0241_u32; 74 | 75 | let m: [u32; 19] = [ 76 | 0x983b41d4, 0x7d780c9e, 0x1ad11d7e, 0xb70391b1, 0xde0b35da, 0x2dc62f83, 0xe7b78d63, 77 | 0x06ca0ea0, 0x7e941b7b, 0xe91348f9, 0xfcb170e2, 0x217fecd9, 0x7f9f68ad, 0xb16e5d7d, 78 | 0x21e569d2, 0x80ed775c, 0xebde3f40, 0x93c53881, 0x00000000, 79 | ]; 80 | 81 | let mac = 0xfae8ff0b_u32; 82 | 83 | let mut eia = EIA::new(&ik, count, bearer, direction); 84 | let rs = eia.gen_mac(&m, length); 85 | assert_eq!(mac, rs) 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /gm-sm2/README.md: -------------------------------------------------------------------------------- 1 | # gm-sm2 2 | 3 | A Pure Rust High-Performance Implementation of China's Standards of Encryption Algorithms SM2 4 | 5 | - ✅ **SM2 ECDSA**: digital signature algorithm defined in [GBT.32918.2-2016], [ISO.IEC.14888-3] (SM2-2) 6 | - ✅ **SM2 ECDH**: key exchange protocol defined in [GBT.32918.3-2016] (SM2-3) 7 | - ✅ **SM2 PKE**: public key encryption algorithm defined in [GBT.32918.4-2016] (SM2-4) 8 | 9 | ## Example 10 | 11 | ### encrypt & decrypt 12 | 13 | ```rust 14 | use gm_sm2::key::{gen_keypair, CompressModle}; 15 | 16 | fn main() { 17 | let (pk, sk) = gen_keypair(CompressModle::Compressed).unwrap(); 18 | let msg = "你好 world,asjdkajhdjadahkubbhj12893718927391873891,@@!! world,1231 wo12321321313asdadadahello world,hello world".as_bytes(); 19 | let encrypt = pk.encrypt(msg).unwrap(); 20 | let plain = sk.decrypt(&encrypt).unwrap(); 21 | assert_eq!(msg, plain) 22 | } 23 | 24 | ``` 25 | 26 | ### sign & verify 27 | 28 | ```rust 29 | use gm_sm2::key::{gen_keypair, CompressModle}; 30 | fn main() { 31 | let msg = b"hello"; 32 | let (pk, sk) = gen_keypair(CompressModle::Compressed).unwrap(); 33 | let signature = sk.sign(None, msg).unwrap(); 34 | pk.verify(None, msg, &signature).unwrap() 35 | } 36 | 37 | ``` 38 | 39 | ### generate pk & sk from string 40 | 41 | ```rust 42 | use gm_sm2::key::{CompressModle}; 43 | fn main() { 44 | let msg = b"hello"; 45 | let pk_hex = hex::decode("04D5548C7825CBB56150A3506CD57464AF8A1AE0519DFAF3C58221DC810CAF28DD921073768FE3D59CE54E79A49445CF73FED23086537027264D168946D479533E").unwrap(); 46 | let pk = gm_sm2::key::Sm2PublicKey::new(&pk_hex[..], CompressModle::Uncompressed).unwrap(); 47 | let sk_hex = 48 | hex::decode("128b2fa8bd433c6c068c8d803dff79792a519a55171b1b650c23661d15897263").unwrap(); 49 | let sk = gm_sm2::key::Sm2PrivateKey::new(&sk_hex[..], CompressModle::Compressed).unwrap(); 50 | 51 | let signature = sk.sign(None, msg).unwrap(); 52 | pk.verify(None, msg, &signature).unwrap(); 53 | } 54 | 55 | ``` 56 | 57 | 58 | ### key exchange 59 | ```rust 60 | use gm_sm2::exchange::Exchange; 61 | use gm_sm2::key::{gen_keypair, CompressModle}; 62 | 63 | fn main() { 64 | let id_a = "alice123@qq.com"; 65 | let id_b = "bob456@qq.com"; 66 | 67 | let (pk_a, sk_a) = gen_keypair(CompressModle::Compressed).unwrap(); 68 | let (pk_b, sk_b) = gen_keypair(CompressModle::Compressed).unwrap(); 69 | 70 | let mut user_a = Exchange::new(8, Some(id_a), &pk_a, &sk_a, Some(id_b), &pk_b).unwrap(); 71 | let mut user_b = Exchange::new(8, Some(id_b), &pk_b, &sk_b, Some(id_a), &pk_a).unwrap(); 72 | 73 | let ra_point = user_a.exchange_1().unwrap(); 74 | let (rb_point, sb) = user_b.exchange_2(&ra_point).unwrap(); 75 | let sa = user_a.exchange_3(&rb_point, sb).unwrap(); 76 | let succ = user_b.exchange_4(sa, &ra_point).unwrap(); 77 | println!("test_key_exchange = {}", succ); 78 | // assert_eq!(user_a.k, user_b.k); 79 | } 80 | 81 | ``` 82 | 83 | ## Reference 84 | [GmSSL](https://github.com/guanzhi/GmSSL) 85 | -------------------------------------------------------------------------------- /gm-sm2/src/error.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::Display; 2 | use std::fmt::Formatter; 3 | 4 | pub type Sm2Result = Result; 5 | 6 | #[derive(PartialEq)] 7 | pub enum Sm2Error { 8 | NotOnCurve, 9 | FieldSqrtError, 10 | InvalidDer, 11 | InvalidPublic, 12 | InvalidPrivate, 13 | ZeroDivisor, 14 | ZeroPoint, 15 | InvalidPoint, 16 | CheckPointErr, 17 | ZeroData, 18 | HashNotEqual, 19 | IdTooLong, 20 | ZeroFiled, 21 | InvalidFieldLen, 22 | ZeroSig, 23 | InvalidDigestLen, 24 | InvalidDigest, 25 | InvalidSecretKey, 26 | KdfHashError, 27 | } 28 | 29 | impl ::std::fmt::Debug for Sm2Error { 30 | fn fmt(&self, f: &mut Formatter<'_>) -> ::std::fmt::Result { 31 | write!(f, "{}", self) 32 | } 33 | } 34 | 35 | impl From for &str { 36 | fn from(e: Sm2Error) -> Self { 37 | match e { 38 | Sm2Error::NotOnCurve => "the point not on curve", 39 | Sm2Error::FieldSqrtError => "field elem sqrt error", 40 | Sm2Error::InvalidDer => "invalid der", 41 | Sm2Error::InvalidPublic => "invalid public key", 42 | Sm2Error::InvalidPrivate => "invalid private key", 43 | Sm2Error::ZeroDivisor => "zero has no inversion", 44 | Sm2Error::ZeroPoint => "cannot convert the infinite point to affine", 45 | Sm2Error::InvalidPoint => "invalid jacobian point", 46 | Sm2Error::CheckPointErr => "check point error", 47 | Sm2Error::ZeroData => "the vector is zero", 48 | Sm2Error::HashNotEqual => "hash not equal", 49 | Sm2Error::IdTooLong => "ID is too long", 50 | Sm2Error::ZeroFiled => "zero has no inversion in filed", 51 | Sm2Error::InvalidFieldLen => "a SCA-256 field element must be 32-byte long", 52 | Sm2Error::ZeroSig => "the signature is zero, cannot sign", 53 | Sm2Error::InvalidDigestLen => "the length of digest must be 32-bytes", 54 | Sm2Error::InvalidSecretKey => "invalid secret key", 55 | Sm2Error::KdfHashError => "KDF hash error", 56 | Sm2Error::InvalidDigest => "invalid signature digest", 57 | } 58 | } 59 | } 60 | 61 | impl Display for Sm2Error { 62 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { 63 | let err_msg = match self { 64 | Sm2Error::NotOnCurve => "the point not on curve", 65 | Sm2Error::FieldSqrtError => "field elem sqrt error", 66 | Sm2Error::InvalidDer => "invalid der", 67 | Sm2Error::InvalidPublic => "invalid public key", 68 | Sm2Error::InvalidPrivate => "invalid private key", 69 | Sm2Error::ZeroDivisor => "zero has no inversion", 70 | Sm2Error::ZeroPoint => "cannot convert the infinite point to affine", 71 | Sm2Error::InvalidPoint => "invalid jacobian point", 72 | Sm2Error::CheckPointErr => "check point error", 73 | Sm2Error::ZeroData => "the vector is zero", 74 | Sm2Error::HashNotEqual => "hash and cipher not equal", 75 | Sm2Error::IdTooLong => "ID is too long", 76 | Sm2Error::ZeroFiled => "zero has no inversion in filed", 77 | Sm2Error::InvalidFieldLen => "a SCA-256 field element must be 32-byte long", 78 | Sm2Error::ZeroSig => "the signature is zero, cannot sign", 79 | Sm2Error::InvalidDigestLen => "the length of digest must be 32-bytes", 80 | Sm2Error::InvalidSecretKey => "invalid secret key", 81 | Sm2Error::KdfHashError => "KDF hash error", 82 | Sm2Error::InvalidDigest => "invalid signature digest", 83 | }; 84 | write!(f, "{}", err_msg) 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /gm-sm9/src/error.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::Display; 2 | use std::fmt::Formatter; 3 | 4 | pub type Sm9Result = Result; 5 | 6 | #[derive(PartialEq)] 7 | pub enum Sm9Error { 8 | NotOnCurve, 9 | FieldSqrtError, 10 | InvalidDer, 11 | InvalidPublic, 12 | InvalidPrivate, 13 | ZeroDivisor, 14 | ZeroPoint, 15 | InvalidPoint, 16 | CheckPointErr, 17 | ZeroData, 18 | HashNotEqual, 19 | IdTooLong, 20 | ZeroFiled, 21 | InvalidFieldLen, 22 | ZeroSig, 23 | InvalidDigestLen, 24 | InvalidDigest, 25 | InvalidSecretKey, 26 | KdfHashError, 27 | } 28 | 29 | impl ::std::fmt::Debug for Sm9Error { 30 | fn fmt(&self, f: &mut Formatter<'_>) -> ::std::fmt::Result { 31 | write!(f, "{}", self) 32 | } 33 | } 34 | 35 | impl From for &str { 36 | fn from(e: Sm9Error) -> Self { 37 | match e { 38 | Sm9Error::NotOnCurve => "the point not on curve", 39 | Sm9Error::FieldSqrtError => "field elem sqrt error", 40 | Sm9Error::InvalidDer => "invalid der", 41 | Sm9Error::InvalidPublic => "invalid public key", 42 | Sm9Error::InvalidPrivate => "invalid private key", 43 | Sm9Error::ZeroDivisor => "zero has no inversion", 44 | Sm9Error::ZeroPoint => "cannot convert the infinite point to affine", 45 | Sm9Error::InvalidPoint => "invalid jacobian point", 46 | Sm9Error::CheckPointErr => "check point error", 47 | Sm9Error::ZeroData => "the vector is zero", 48 | Sm9Error::HashNotEqual => "hash not equal", 49 | Sm9Error::IdTooLong => "ID is too long", 50 | Sm9Error::ZeroFiled => "zero has no inversion in filed", 51 | Sm9Error::InvalidFieldLen => "a SCA-256 field element must be 32-byte long", 52 | Sm9Error::ZeroSig => "the signature is zero, cannot sign", 53 | Sm9Error::InvalidDigestLen => "the length of digest must be 32-bytes", 54 | Sm9Error::InvalidSecretKey => "invalid secret key", 55 | Sm9Error::KdfHashError => "KDF hash error", 56 | Sm9Error::InvalidDigest => "invalid signature digest", 57 | } 58 | } 59 | } 60 | 61 | impl Display for Sm9Error { 62 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { 63 | let err_msg = match self { 64 | Sm9Error::NotOnCurve => "the point not on curve", 65 | Sm9Error::FieldSqrtError => "field elem sqrt error", 66 | Sm9Error::InvalidDer => "invalid der", 67 | Sm9Error::InvalidPublic => "invalid public key", 68 | Sm9Error::InvalidPrivate => "invalid private key", 69 | Sm9Error::ZeroDivisor => "zero has no inversion", 70 | Sm9Error::ZeroPoint => "cannot convert the infinite point to affine", 71 | Sm9Error::InvalidPoint => "invalid jacobian point", 72 | Sm9Error::CheckPointErr => "check point error", 73 | Sm9Error::ZeroData => "the vector is zero", 74 | Sm9Error::HashNotEqual => "hash and cipher not equal", 75 | Sm9Error::IdTooLong => "ID is too long", 76 | Sm9Error::ZeroFiled => "zero has no inversion in filed", 77 | Sm9Error::InvalidFieldLen => "a SCA-256 field element must be 32-byte long", 78 | Sm9Error::ZeroSig => "the signature is zero, cannot sign", 79 | Sm9Error::InvalidDigestLen => "the length of digest must be 32-bytes", 80 | Sm9Error::InvalidSecretKey => "invalid secret key", 81 | Sm9Error::KdfHashError => "KDF hash error", 82 | Sm9Error::InvalidDigest => "invalid signature digest", 83 | }; 84 | write!(f, "{}", err_msg) 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /gm-sm9/README.md: -------------------------------------------------------------------------------- 1 | # gm-sm9 2 | 3 | A Pure Rust High-Performance Implementation of China's Standards of Encryption Algorithms SM9 4 | 5 | 6 | ## Example 7 | 8 | ### encrypt & decrypt 9 | ```rust 10 | use gm_sm9::key::{Sm9EncMasterKey,Sm9EncKey}; 11 | use gm_sm9::points::{Point, TwistPoint}; 12 | use gm_sm9::u256::u256_from_be_bytes; 13 | 14 | fn main() { 15 | 16 | let data: [u8; 21] = [ 17 | 0x43, 0x68, 0x69, 0x6E, 0x65, 0x73, 0x65, 0x20, 0x49, 0x42, 0x53, 0x20, 0x73, 0x74, 18 | 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x64, 19 | ]; 20 | println!("Message = {:?}", &data); 21 | 22 | let id = [0x42, 0x6F, 0x62u8]; 23 | let ke = u256_from_be_bytes( 24 | &hex::decode("0001EDEE3778F441F8DEA3D9FA0ACC4E07EE36C93F9A08618AF4AD85CEDE1C22") 25 | .unwrap(), 26 | ); 27 | 28 | let msk = Sm9EncMasterKey { 29 | ke, 30 | ppube: Point::g_mul(&ke), 31 | }; 32 | 33 | let r = msk.extract_key(&id); 34 | let r_de = TwistPoint::from_hex( 35 | [ 36 | "115BAE85F5D8BC6C3DBD9E5342979ACCCF3C2F4F28420B1CB4F8C0B59A19B158", 37 | "94736ACD2C8C8796CC4785E938301A139A059D3537B6414140B2D31EECF41683", 38 | ], 39 | [ 40 | "27538A62E7F7BFB51DCE08704796D94C9D56734F119EA44732B50E31CDEB75C1", 41 | "7AA5E47570DA7600CD760A0CF7BEAF71C447F3844753FE74FA7BA92CA7D3B55F", 42 | ], 43 | ); 44 | assert_eq!(true, r.unwrap().de.point_equals(&r_de)); 45 | 46 | let ret = msk.encrypt(&id, &data); 47 | println!("Ciphertext = {:?}", ret); 48 | 49 | let m = r.unwrap().decrypt(&id, &ret).expect("Decryption failed"); 50 | println!("Plaintext = {:?}", &m); 51 | assert_eq!(true, data == m.as_slice()); 52 | } 53 | 54 | ``` 55 | 56 | ### sign & verify 57 | ```rust 58 | use gm_sm9::key::{Sm9SignMasterKey, Sm9SignKey}; 59 | use gm_sm9::points::{Point, TwistPoint}; 60 | use gm_sm9::u256::u256_from_be_bytes; 61 | fn main() { 62 | let data: [u8; 20] = [ 63 | 0x43, 0x68, 0x69, 0x6E, 0x65, 0x73, 0x65, 0x20, 0x49, 0x42, 0x53, 0x20, 0x73, 0x74, 64 | 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 65 | ]; 66 | 67 | let ida = [0x41, 0x6C, 0x69, 0x63, 0x65u8]; 68 | 69 | let ks = u256_from_be_bytes( 70 | &hex::decode("000130E78459D78545CB54C587E02CF480CE0B66340F319F348A1D5B1F2DC5F4") 71 | .unwrap(), 72 | ); 73 | let msk = Sm9SignMasterKey { 74 | ks, 75 | ppubs: TwistPoint::g_mul(&ks), 76 | }; 77 | 78 | let r_ds = Point::from_hex([ 79 | "A5702F05CF1315305E2D6EB64B0DEB923DB1A0BCF0CAFF90523AC8754AA69820", 80 | "78559A844411F9825C109F5EE3F52D720DD01785392A727BB1556952B2B013D3", 81 | ]); 82 | let r = msk.extract_key(&ida); 83 | let ps = r.unwrap(); 84 | assert_eq!(true, ps.ds.point_equals(&r_ds)); 85 | 86 | println!("Message = {:?}", &data); 87 | let (h, s) = ps.sign(&data).unwrap(); 88 | println!("Sign H = {:?}", &h); 89 | println!("Sign S = {:?}", &s); 90 | 91 | let r = msk.verify_sign(&ida, &data, &h, &s); 92 | println!("VersionSign ={:?}", &r); 93 | } 94 | 95 | ``` 96 | 97 | ### key exchange 98 | ```rust 99 | use gm_sm9::key::{Sm9EncMasterKey,Sm9EncKey}; 100 | use gm_sm9::points::{Point, TwistPoint}; 101 | fn main() { 102 | let msk: Sm9EncMasterKey = Sm9EncMasterKey::master_key_generate(); 103 | let klen = 20usize; 104 | let ida = [0x41, 0x6C, 0x69, 0x63, 0x65u8]; 105 | let idb = [0x42, 0x6F, 0x62u8]; 106 | let key_a: Sm9EncKey = msk.extract_exch_key(&ida).unwrap(); 107 | let key_b: Sm9EncKey = msk.extract_exch_key(&idb).unwrap(); 108 | 109 | let (ra, ra_) = exch_step_1a(&msk, &idb); 110 | let (rb, skb) = exch_step_1b(&msk, &ida, &idb, &key_b, &ra, klen).unwrap(); 111 | let ska = exch_step_2a(&msk, &ida, &idb, &key_a, ra_, &ra, &rb, klen).unwrap(); 112 | println!("SKB = {:?}", &skb); 113 | println!("SKA = {:?}", &ska); 114 | for i in 0..klen { 115 | if ska[i] != skb[i] { 116 | println!("Exchange key different at byte index: {}", i) 117 | } 118 | } 119 | } 120 | 121 | ``` 122 | 123 | 124 | ## Reference 125 | [GmSSL](https://github.com/guanzhi/GmSSL) 126 | -------------------------------------------------------------------------------- /gm-sm2/src/fields/fn64.rs: -------------------------------------------------------------------------------- 1 | use crate::u256::{ 2 | SM2_ONE, U256, u256_add, u256_cmp, u256_mul, u256_sub, u512_add, 3 | }; 4 | 5 | /// 6 | /// n = 0xfffffffeffffffffffffffffffffffff7203df6b21c6052b53bbf40939d54123 7 | pub const SM2_N: U256 = [ 8 | 0x53bbf40939d54123, 9 | 0x7203df6b21c6052b, 10 | 0xffffffffffffffff, 11 | 0xfffffffeffffffff, 12 | ]; 13 | 14 | /// 2^256 - n = 0x10000000000000000000000008dfc2094de39fad4ac440bf6c62abedd 15 | pub const SM2_N_NEG: U256 = [ 16 | 0xac440bf6c62abedd, 17 | 0x8dfc2094de39fad4, 18 | 0x0000000000000000, 19 | 0x0000000100000000, 20 | ]; 21 | 22 | /// N - 2 23 | pub const SM2_N_MINUS_TWO: U256 = [ 24 | 0x53bbf40939d54121, 25 | 0x7203df6b21c6052b, 26 | 0xffffffffffffffff, 27 | 0xfffffffeffffffff, 28 | ]; 29 | 30 | pub const SM2_N_PRIME: U256 = [ 31 | 0x327f9e8872350975, 32 | 0xdf1e8d34fc8319a5, 33 | 0x2b0068d3b08941d4, 34 | 0x6f39132f82e4c7bc, 35 | ]; 36 | 37 | pub const SM2_MOD_N_2E512: U256 = [ 38 | 0x901192af7c114f20, 39 | 0x3464504ade6fa2fa, 40 | 0x620fc84c3affe0d4, 41 | 0x1eb5e412a22b3d3b, 42 | ]; 43 | 44 | pub fn fn_add(a: &U256, b: &U256) -> U256 { 45 | let (r, c) = u256_add(a, b); 46 | if c { 47 | // a + b - n = (a + b - 2^256) + (2^256 - n) 48 | return u256_add(&r, &SM2_N_NEG).0; 49 | } 50 | if u256_cmp(&r, &SM2_N) >= 0 { 51 | return u256_sub(&r, &SM2_N).0; 52 | } 53 | r 54 | } 55 | 56 | pub fn fn_sub(a: &U256, b: &U256) -> U256 { 57 | let (mut r, c) = u256_sub(a, b); 58 | if c { 59 | r = u256_sub(&r, &SM2_N_NEG).0 60 | } 61 | r 62 | } 63 | 64 | pub fn fn_to_mont(a: &U256) -> U256 { 65 | mont_mul(a, &SM2_MOD_N_2E512) 66 | } 67 | 68 | pub fn fn_from_mont(a: &U256) -> U256 { 69 | mont_mul(a, &SM2_ONE) 70 | } 71 | 72 | pub fn fn_mul(a: &U256, b: &U256) -> U256 { 73 | let mont_a = fn_to_mont(a); 74 | let mont_b = fn_to_mont(b); 75 | let mut r = mont_mul(&mont_a, &mont_b); 76 | r = fn_from_mont(&r); 77 | r 78 | } 79 | 80 | fn mont_mul(a: &U256, b: &U256) -> U256 { 81 | let mut r = [0u64; 4]; 82 | let mut z = [0u64; 8]; 83 | let mut t = [0u64; 8]; 84 | 85 | // z = a * b 86 | z = u256_mul(a, b); 87 | 88 | // t = low(z) * n' 89 | let z_low = [z[0], z[1], z[2], z[3]]; 90 | let t1 = u256_mul(&z_low, &SM2_N_PRIME); 91 | t[0] = t1[0]; 92 | t[1] = t1[1]; 93 | t[2] = t1[2]; 94 | t[3] = t1[3]; 95 | 96 | // t = low(t) * n 97 | let t_low = [t[0], t[1], t[2], t[3]]; 98 | t = u256_mul(&t_low, &SM2_N); 99 | 100 | // z = z + t 101 | let (sum, c) = u512_add(&z, &t); 102 | z = sum; 103 | 104 | // r = high(r) 105 | r = [z[4], z[5], z[6], z[7]]; 106 | if c { 107 | r = u256_add(&r, &SM2_N_NEG).0; 108 | } else if u256_cmp(&r, &SM2_N) >= 0 { 109 | r = u256_sub(&r, &SM2_N).0 110 | } 111 | r 112 | } 113 | 114 | pub fn fn_pow(a: &U256, e: &U256) -> U256 { 115 | let mont_a = fn_to_mont(a); 116 | let mut r = SM2_N_NEG; 117 | let mut w = 0u64; 118 | for i in (0..4).rev() { 119 | w = e[i]; 120 | for _j in 0..64 { 121 | r = mont_mul(&r, &r); 122 | if w & 0x8000000000000000 != 0 { 123 | r = mont_mul(&r, &mont_a); 124 | } 125 | w <<= 1; 126 | } 127 | } 128 | r = fn_from_mont(&r); 129 | r 130 | } 131 | 132 | pub fn fn_inv(a: &U256) -> U256 { 133 | let mont_a = fn_to_mont(a); 134 | let mut r = fn_pow(&mont_a, &SM2_N_MINUS_TWO); 135 | r = fn_from_mont(&r); 136 | r 137 | } 138 | 139 | #[cfg(test)] 140 | mod test_mod_operation { 141 | use num_bigint::BigUint; 142 | 143 | use crate::fields::fn64::fn_mul; 144 | 145 | #[test] 146 | fn test_mod_op() { 147 | let a: [u64; 4] = [ 148 | 0x715a4589334c74c7, 149 | 0x8fe30bbff2660be1, 150 | 0x5f9904466a39c994, 151 | 0x32c4ae2c1f198119, 152 | ]; 153 | 154 | let b: [u64; 4] = [ 155 | 0x02df32e52139f0a0, 156 | 0xd0a9877cc62a4740, 157 | 0x59bdcee36b692153, 158 | 0xbc3736a2f4f6779c, 159 | ]; 160 | 161 | let r = fn_mul(&a, &b); 162 | println!("{:x?}", r); 163 | 164 | let a1 = BigUint::from_bytes_be( 165 | &hex::decode("32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7") 166 | .unwrap(), 167 | ); 168 | 169 | let b1 = BigUint::from_bytes_be( 170 | &hex::decode("bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0") 171 | .unwrap(), 172 | ); 173 | 174 | let n1 = BigUint::from_bytes_be( 175 | &hex::decode("fffffffeffffffffffffffffffffffff7203df6b21c6052b53bbf40939d54123") 176 | .unwrap(), 177 | ); 178 | 179 | let r = ((&a1 * &b1) % n1).to_u64_digits(); 180 | println!("{:x?}", r); 181 | 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /gm-sm9/src/fields.rs: -------------------------------------------------------------------------------- 1 | use crate::u256::{u256_add, u256_cmp, u256_from_be_bytes, u256_mul, u256_sub, SM9_ONE, U256}; 2 | use crate::{ 3 | SM9_N, SM9_N_BARRETT_MU, SM9_N_MINUS_ONE, SM9_N_MINUS_TWO, SM9_N_NEG, 4 | SM9_U256_N_MINUS_ONE_BARRETT_MU, 5 | }; 6 | use rand::RngCore; 7 | use std::fmt::Debug; 8 | 9 | pub mod fp; 10 | pub(crate) mod fp12; 11 | pub(crate) mod fp2; 12 | pub(crate) mod fp4; 13 | 14 | pub trait FieldElement: Sized + Copy + Clone + PartialEq + Eq + Debug { 15 | fn zero() -> Self; 16 | fn one() -> Self; 17 | fn is_zero(&self) -> bool; 18 | fn fp_sqr(&self) -> Self; 19 | fn fp_double(&self) -> Self; 20 | fn fp_triple(&self) -> Self; 21 | fn fp_add(&self, rhs: &Self) -> Self; 22 | fn fp_sub(&self, rhs: &Self) -> Self; 23 | fn fp_mul(&self, rhs: &Self) -> Self; 24 | fn fp_neg(&self) -> Self; 25 | fn fp_div2(&self) -> Self; 26 | fn fp_inv(&self) -> Self; 27 | 28 | fn to_bytes_be(&self) -> Vec; 29 | } 30 | 31 | #[inline(always)] 32 | pub fn fn_random_u256() -> U256 { 33 | let mut rng = rand::thread_rng(); 34 | let mut buf: [u8; 32] = [0; 32]; 35 | let mut ret; 36 | loop { 37 | rng.fill_bytes(&mut buf[..]); 38 | ret = u256_from_be_bytes(&buf); 39 | if ret < SM9_N_MINUS_ONE && ret != [0, 0, 0, 0] { 40 | break; 41 | } 42 | } 43 | ret 44 | } 45 | 46 | pub fn mod_n_add(a: &U256, b: &U256) -> U256 { 47 | let (r, c) = u256_add(a, b); 48 | if c { 49 | // a + b - n = (a + b - 2^256) + (2^256 - n) 50 | return u256_add(&r, &SM9_N_NEG).0; 51 | } 52 | if u256_cmp(&r, &SM9_N) >= 0 { 53 | return u256_sub(&r, &SM9_N).0; 54 | } 55 | r 56 | } 57 | 58 | pub fn mod_n_sub(a: &U256, b: &U256) -> U256 { 59 | let (mut r, c) = u256_sub(a, b); 60 | if c { 61 | r = u256_sub(&r, &SM9_N_NEG).0 62 | } 63 | r 64 | } 65 | 66 | #[inline(always)] 67 | pub fn u320_mul(a: &[u64; 5], b: &[u64; 5]) -> [u64; 10] { 68 | let mut a_: [u64; 10] = [0; 10]; 69 | let mut b_: [u64; 10] = [0; 10]; 70 | let mut ret: [u64; 10] = [0; 10]; 71 | let mut s: [u64; 20] = [0; 20]; 72 | 73 | for i in 0..5 { 74 | a_[2 * i] = a[i] & 0xffffffff; 75 | b_[2 * i] = b[i] & 0xffffffff; 76 | a_[2 * i + 1] = a[i] >> 32; 77 | b_[2 * i + 1] = b[i] >> 32; 78 | } 79 | 80 | let mut u = 0; 81 | for i in 0..10 { 82 | u = 0; 83 | for j in 0..10 { 84 | u = s[i + j] + a_[i] * b_[j] + u; 85 | s[i + j] = u & 0xffffffff; 86 | u >>= 32; 87 | } 88 | s[i + 10] = u; 89 | } 90 | 91 | for i in 0..10 { 92 | ret[i] = (s[2 * i + 1] << 32) | s[2 * i]; 93 | } 94 | ret 95 | } 96 | 97 | pub fn mod_n_mul(a: &U256, b: &U256) -> U256 { 98 | let mut r = [0, 0, 0, 0]; 99 | 100 | let z = u256_mul(a, b); 101 | 102 | // (z // 2^192) = z[3-7] 103 | let z1: [u64; 5] = [z[3], z[4], z[5], z[6], z[7]]; 104 | let h = u320_mul(&z1, &SM9_N_BARRETT_MU); 105 | 106 | // (h // 2^320) = h[5-9] 107 | let h1: [u64; 4] = [h[5], h[6], h[7], h[8]]; 108 | let mut s = u256_mul(&h1, &SM9_N); 109 | 110 | s[4] += SM9_N[0] * h[9]; 111 | 112 | let mut carry = 0; 113 | let (t0, overflow) = z[0].overflowing_sub(s[0]); 114 | r[0] = t0; 115 | carry = overflow as u64; 116 | 117 | let (t1, overflow) = z[1].overflowing_sub(carry); 118 | let (t1, overflow2) = t1.overflowing_sub(s[1]); 119 | r[1] = t1; 120 | carry = (overflow || overflow2) as u64; 121 | 122 | let (t2, overflow) = z[2].overflowing_sub(carry); 123 | let (t2, overflow2) = t2.overflowing_sub(s[2]); 124 | r[2] = t2; 125 | carry = (overflow || overflow2) as u64; 126 | 127 | let (t3, overflow) = z[3].overflowing_sub(carry); 128 | let (t3, overflow2) = t3.overflowing_sub(s[3]); 129 | r[3] = t3; 130 | carry = (overflow || overflow2) as u64; 131 | 132 | // s[4] holds the temporary value for r[4] 133 | let (t4, overflow) = z[4].overflowing_sub(carry); 134 | s[4] = t4.wrapping_sub(s[4]); 135 | 136 | if s[4] > 0 || u256_cmp(&r, &SM9_N) >= 0 { 137 | r = u256_sub(&r, &SM9_N).0; 138 | } 139 | r 140 | } 141 | 142 | pub fn mod_n_pow(a: &U256, e: &U256) -> U256 { 143 | let mut r = SM9_ONE; 144 | for i in (0..4).rev() { 145 | let mut w = e[i]; 146 | for _ in 0..64 { 147 | r = mod_n_mul(&r, &r); 148 | if w & 0x8000000000000000 != 0 { 149 | r = mod_n_mul(&r, a); 150 | } 151 | w <<= 1; 152 | } 153 | } 154 | r 155 | } 156 | 157 | pub fn mod_n_inv(a: &U256) -> U256 { 158 | mod_n_pow(a, &SM9_N_MINUS_TWO) 159 | } 160 | 161 | pub fn mod_n_from_hash(ha: &[u8]) -> U256 { 162 | let mut h = SM9_ONE; 163 | let mut z: [u64; 5] = [0; 5]; 164 | for i in 0..5 { 165 | z[4 - i] = getu64(&ha[8 * i..]); 166 | } 167 | 168 | let z1 = [z[3], z[4], 0, 0]; 169 | let mut r = u256_mul(&z1, &SM9_U256_N_MINUS_ONE_BARRETT_MU); 170 | 171 | let (sum1, carry1) = r[4].overflowing_add(z[3]); 172 | r[4] = sum1; 173 | let t = z[4] + carry1 as u64; 174 | let (sum2, carry2) = r[5].overflowing_add(t); 175 | r[5] = sum2; 176 | r[6] = u64::from(carry2); 177 | 178 | r = u256_mul(&[r[5], r[6], 0, 0], &SM9_N_MINUS_ONE); 179 | h = u256_sub(&[z[0], z[1], z[2], z[3]], &[r[0], r[1], r[2], r[3]]).0; 180 | h = mod_n_add(&h, &SM9_ONE); 181 | h 182 | } 183 | 184 | fn getu64(bytes: &[u8]) -> u64 { 185 | let mut arr = [0u8; 8]; 186 | arr.copy_from_slice(&bytes[..8]); 187 | u64::from_be_bytes(arr) 188 | } 189 | -------------------------------------------------------------------------------- /gm-sm9/src/fields/fp4.rs: -------------------------------------------------------------------------------- 1 | use crate::fields::fp::Fp; 2 | use crate::fields::fp2::Fp2; 3 | use crate::fields::FieldElement; 4 | 5 | #[derive(Debug, Copy, Clone)] 6 | pub struct Fp4 { 7 | pub(crate) c0: Fp2, 8 | pub(crate) c1: Fp2, 9 | } 10 | 11 | impl Fp4 { 12 | pub(crate) fn fp_mul_fp(&self, k: &Fp) -> Fp4 { 13 | Self { 14 | c0: self.c0.fp_mul_fp(k), 15 | c1: self.c1.fp_mul_fp(k), 16 | } 17 | } 18 | 19 | pub(crate) fn fp_mul_fp2(&self, k: &Fp2) -> Fp4 { 20 | Self { 21 | c0: self.c0.fp_mul(k), 22 | c1: self.c1.fp_mul(k), 23 | } 24 | } 25 | } 26 | 27 | impl PartialEq for Fp4 { 28 | fn eq(&self, other: &Self) -> bool { 29 | self.c0.eq(&other.c0) && self.c1.eq(&other.c1) 30 | } 31 | } 32 | 33 | impl Eq for Fp4 {} 34 | 35 | impl FieldElement for Fp4 { 36 | fn zero() -> Self { 37 | Fp4 { 38 | c0: Fp2::zero(), 39 | c1: Fp2::zero(), 40 | } 41 | } 42 | 43 | fn one() -> Self { 44 | Fp4 { 45 | c0: Fp2::one(), 46 | c1: Fp2::zero(), 47 | } 48 | } 49 | 50 | fn is_zero(&self) -> bool { 51 | self.c0.is_zero() && self.c1.is_zero() 52 | } 53 | 54 | fn fp_sqr(&self) -> Self { 55 | let mut r0 = Fp2::zero(); 56 | let mut r1 = Fp2::zero(); 57 | let mut t = Fp2::zero(); 58 | 59 | r1 = self.c0.fp_add(&self.c1); 60 | r1 = r1.fp_sqr(); 61 | 62 | r0 = self.c0.fp_sqr(); 63 | t = self.c1.fp_sqr(); 64 | 65 | r1 = r1.fp_sub(&r0); 66 | r1 = r1.fp_sub(&t); 67 | 68 | t = t.a_mul_u(); 69 | r0 = r0.fp_add(&t); 70 | 71 | Self { c0: r0, c1: r1 } 72 | } 73 | 74 | fn fp_double(&self) -> Self { 75 | Self { 76 | c0: self.c0.fp_double(), 77 | c1: self.c1.fp_double(), 78 | } 79 | } 80 | 81 | fn fp_triple(&self) -> Self { 82 | Self { 83 | c0: self.c0.fp_triple(), 84 | c1: self.c1.fp_triple(), 85 | } 86 | } 87 | 88 | fn fp_add(&self, rhs: &Self) -> Self { 89 | Self { 90 | c0: self.c0.fp_add(&rhs.c0), 91 | c1: self.c1.fp_add(&rhs.c1), 92 | } 93 | } 94 | 95 | fn fp_sub(&self, rhs: &Self) -> Self { 96 | Self { 97 | c0: self.c0.fp_sub(&rhs.c0), 98 | c1: self.c1.fp_sub(&rhs.c1), 99 | } 100 | } 101 | 102 | fn fp_mul(&self, rhs: &Self) -> Self { 103 | let mut r0 = Fp2::zero(); 104 | let mut r1 = Fp2::zero(); 105 | let mut t = Fp2::zero(); 106 | 107 | r0 = self.c0.fp_add(&self.c1); 108 | t = rhs.c0.fp_add(&rhs.c1); 109 | r1 = t.fp_mul(&r0); 110 | 111 | r0 = self.c0.fp_mul(&rhs.c0); 112 | t = self.c1.fp_mul(&rhs.c1); 113 | 114 | r1 = r1.fp_sub(&r0); 115 | r1 = r1.fp_sub(&t); 116 | 117 | t = t.a_mul_u(); 118 | r0 = r0.fp_add(&t); 119 | 120 | Self { c0: r0, c1: r1 } 121 | } 122 | 123 | fn fp_neg(&self) -> Self { 124 | Self { 125 | c0: self.c0.fp_neg(), 126 | c1: self.c1.fp_neg(), 127 | } 128 | } 129 | 130 | fn fp_div2(&self) -> Self { 131 | Self { 132 | c0: self.c0.fp_div2(), 133 | c1: self.c1.fp_div2(), 134 | } 135 | } 136 | 137 | fn fp_inv(&self) -> Self { 138 | let mut r0 = Fp2::zero(); 139 | let mut r1 = Fp2::zero(); 140 | let mut k = Fp2::zero(); 141 | 142 | k = self.c1.sqr_u(); 143 | r0 = self.c0.fp_sqr(); 144 | k = k.fp_sub(&r0); 145 | k = k.fp_inv(); 146 | 147 | r0 = self.c0.fp_mul(&k); 148 | r0 = r0.fp_neg(); 149 | 150 | r1 = self.c1.fp_mul(&k); 151 | 152 | Self { c0: r0, c1: r1 } 153 | } 154 | 155 | fn to_bytes_be(&self) -> Vec { 156 | let mut bytes: Vec = vec![]; 157 | bytes.extend_from_slice(self.c1.to_bytes_be().as_slice()); 158 | bytes.extend_from_slice(self.c0.to_bytes_be().as_slice()); 159 | bytes 160 | } 161 | } 162 | 163 | impl Fp4 { 164 | pub(crate) fn mont_one() -> Self { 165 | Fp4 { 166 | c0: Fp2 { 167 | c0: [ 168 | 0x1a9064d81caeba83, 169 | 0xde0d6cb4e5851124, 170 | 0x29fc54b00a7138ba, 171 | 0x49bffffffd5c590e, 172 | ], 173 | c1: [0, 0, 0, 0], 174 | }, 175 | c1: Fp2::zero(), 176 | } 177 | } 178 | 179 | pub(crate) fn fp_mul_v(&self, b: &Self) -> Self { 180 | let mut r0 = Fp2::zero(); 181 | let mut r1 = Fp2::zero(); 182 | let mut t = Fp2::zero(); 183 | 184 | r0 = self.c0.fp_mul_u(&b.c1); 185 | t = self.c1.fp_mul_u(&b.c0); 186 | r0 = r0.fp_add(&t); 187 | 188 | r1 = self.c0.fp_mul(&b.c0); 189 | t = self.c1.fp_mul_u(&b.c1); 190 | r1 = r1.fp_add(&t); 191 | 192 | Self { c0: r0, c1: r1 } 193 | } 194 | 195 | pub(crate) fn a_mul_v(&self) -> Self { 196 | let mut r0 = Fp2::zero(); 197 | let mut a0 = Fp2::zero(); 198 | let mut a1 = Fp2::zero(); 199 | 200 | a0 = self.c0; 201 | a1 = self.c1; 202 | 203 | //r1 = a0 204 | //r0 = a1 * u 205 | r0 = a1.a_mul_u(); 206 | 207 | Self { c0: r0, c1: a0 } 208 | } 209 | 210 | pub(crate) fn conjugate(&self) -> Self { 211 | let r0 = self.c0; 212 | let r1 = self.c1.fp_neg(); 213 | Self { c0: r0, c1: r1 } 214 | } 215 | 216 | pub(crate) fn sqr_v(&self) -> Self { 217 | let mut r0 = Fp2::zero(); 218 | let mut r1 = Fp2::zero(); 219 | let mut t = Fp2::zero(); 220 | 221 | t = self.c0.fp_mul_u(&self.c1); 222 | r0 = t.fp_double(); 223 | 224 | r1 = self.c0.fp_sqr(); 225 | t = self.c1.sqr_u(); 226 | r1 = r1.fp_add(&t); 227 | 228 | Self { c0: r0, c1: r1 } 229 | } 230 | } 231 | -------------------------------------------------------------------------------- /gm-sm2/src/pkcs.rs: -------------------------------------------------------------------------------- 1 | use std::str::FromStr; 2 | 3 | use pkcs8::der::zeroize::Zeroizing; 4 | use pkcs8::der::{Decode, Encode}; 5 | use pkcs8::{ 6 | der, DecodePublicKey, Document, EncodePrivateKey, EncodePublicKey, PrivateKeyInfo, 7 | SecretDocument, SubjectPublicKeyInfoRef, 8 | }; 9 | use sec1::EcPrivateKey; 10 | 11 | use crate::error::Sm2Result; 12 | use crate::key::{Sm2PrivateKey, Sm2PublicKey}; 13 | use crate::p256_ecc::Point; 14 | use crate::{ALGORITHM_IDENTIFIER, ALGORITHM_OID, OID_SM2_PKCS8}; 15 | 16 | impl Sm2PrivateKey { 17 | pub fn to_sec1_der(&self) -> der::Result>> { 18 | let private_key_bytes = Zeroizing::new(self.to_bytes_be()); 19 | let public_key_bytes = self.public_key.to_bytes(false); 20 | let ec_private_key = Zeroizing::new( 21 | EcPrivateKey { 22 | private_key: &private_key_bytes, 23 | parameters: None, 24 | public_key: Some(&public_key_bytes), 25 | } 26 | .to_der()?, 27 | ); 28 | Ok(ec_private_key) 29 | } 30 | } 31 | 32 | impl TryFrom> for Sm2PrivateKey { 33 | type Error = der::Error; 34 | 35 | fn try_from(sec1_private_key: EcPrivateKey<'_>) -> Result { 36 | let sk = Self::new(sec1_private_key.private_key) 37 | .map_err(|_| der::Tag::Sequence.value_error())?; 38 | if let Some(pk_bytes) = sec1_private_key.public_key { 39 | let pk = Point::from_byte(pk_bytes).map_err(|_| der::Tag::BitString.value_error())?; 40 | if validate_public_key(&sk, &pk).is_err() { 41 | return Err(der::Tag::BitString.value_error()); 42 | } 43 | } 44 | Ok(sk) 45 | } 46 | } 47 | 48 | #[allow(unused_variables)] 49 | fn validate_public_key(p0: &Sm2PrivateKey, p1: &Point) -> Sm2Result<()> { 50 | // Provide a default "always succeeds" implementation. 51 | // This is the intended default for curve implementations which 52 | // do not provide an arithmetic implementation, since they have no 53 | // way to verify this. 54 | // 55 | Ok(()) 56 | } 57 | 58 | impl TryFrom> for Sm2PrivateKey { 59 | type Error = pkcs8::Error; 60 | 61 | fn try_from(pki: PrivateKeyInfo<'_>) -> Result { 62 | pki.algorithm.assert_oids(ALGORITHM_OID, OID_SM2_PKCS8)?; 63 | let ec_private_key = EcPrivateKey::from_der(pki.private_key)?; 64 | Ok(Self::try_from(ec_private_key)?) 65 | } 66 | } 67 | 68 | impl TryFrom> for Sm2PublicKey { 69 | type Error = pkcs8::spki::Error; 70 | 71 | fn try_from(spki: SubjectPublicKeyInfoRef<'_>) -> Result { 72 | spki.algorithm.assert_oids(ALGORITHM_OID, OID_SM2_PKCS8)?; 73 | let public_key_bytes = spki 74 | .subject_public_key 75 | .as_bytes() 76 | .ok_or_else(|| der::Tag::BitString.value_error())?; 77 | Ok(Sm2PublicKey::new(public_key_bytes).unwrap()) 78 | } 79 | } 80 | 81 | impl EncodePrivateKey for Sm2PrivateKey { 82 | fn to_pkcs8_der(&self) -> pkcs8::Result { 83 | let algorithm_identifier = pkcs8::AlgorithmIdentifierRef { 84 | oid: ALGORITHM_OID, 85 | parameters: Some((&OID_SM2_PKCS8).into()), 86 | }; 87 | let ec_private_key = self.to_sec1_der()?; 88 | let pkcs8_key = PrivateKeyInfo::new(algorithm_identifier, &ec_private_key); 89 | Ok(SecretDocument::encode_msg(&pkcs8_key)?) 90 | } 91 | } 92 | 93 | impl EncodePublicKey for Sm2PublicKey { 94 | fn to_public_key_der(&self) -> pkcs8::spki::Result { 95 | let public_key_bytes = self.to_bytes(false); 96 | let subject_public_key = der::asn1::BitStringRef::new(0, &public_key_bytes)?; 97 | pkcs8::SubjectPublicKeyInfo { 98 | algorithm: ALGORITHM_IDENTIFIER, 99 | subject_public_key, 100 | } 101 | .try_into() 102 | } 103 | } 104 | 105 | impl FromStr for Sm2PublicKey { 106 | type Err = pkcs8::spki::Error; 107 | 108 | fn from_str(s: &str) -> Result { 109 | Self::from_public_key_pem(s).map_err(|e| e) 110 | } 111 | } 112 | 113 | #[cfg(test)] 114 | mod test_pkcs { 115 | use pkcs8::{DecodePrivateKey, DecodePublicKey, EncodePrivateKey, EncodePublicKey, LineEnding}; 116 | 117 | use crate::key::{gen_keypair, Sm2Model, Sm2PrivateKey, Sm2PublicKey}; 118 | 119 | const SM2_PUBLIC_PEM_EXAMPLE: &str = include_str!("../pki/public_key_pkcs8.pem"); 120 | const SM2_PRIVATE_PEM_EXAMPLE: &str = include_str!("../pki/private_key_pkcs8.pem"); 121 | 122 | #[test] 123 | fn test_pkcs8() { 124 | let (pk, sk) = gen_keypair().unwrap(); 125 | let pub_str = pk.to_public_key_pem(LineEnding::CRLF).unwrap(); 126 | let pri_str = sk.to_pkcs8_pem(LineEnding::CRLF).unwrap(); 127 | println!("{}", pub_str.as_str()); 128 | println!("{}", pri_str.as_str()); 129 | 130 | println!("pub key hex: {:?}", pk.to_hex_string(false)); 131 | println!("pri key hex: {:?}", sk.to_hex_string()); 132 | 133 | let sk = Sm2PrivateKey::from_pkcs8_pem(pri_str.as_str()).unwrap(); 134 | let pk = Sm2PublicKey::from_public_key_pem(pub_str.as_str()).unwrap(); 135 | let msg = "你好 world,asjdkajhdjadahkubbhj12893718927391873891,@@!! world,1231 wo12321321313asdadadahello world,hello world".as_bytes(); 136 | let encrypt = pk.encrypt(msg, false, Sm2Model::C1C2C3).unwrap(); 137 | let plain = sk.decrypt(&encrypt, false, Sm2Model::C1C2C3).unwrap(); 138 | assert_eq!(msg, plain) 139 | } 140 | 141 | #[test] 142 | fn test_pkcs8_from_pem_file() { 143 | let sk = Sm2PrivateKey::from_pkcs8_pem(SM2_PRIVATE_PEM_EXAMPLE).unwrap(); 144 | let pk = Sm2PublicKey::from_public_key_pem(SM2_PUBLIC_PEM_EXAMPLE).unwrap(); 145 | let msg = "你好 world,asjdkajhdjadahkubbhj12893718927391873891,@@!! world,1231 wo12321321313asdadadahello world,hello world".as_bytes(); 146 | let encrypt = pk.encrypt(msg, false, Sm2Model::C1C2C3).unwrap(); 147 | let plain = sk.decrypt(&encrypt, false, Sm2Model::C1C2C3).unwrap(); 148 | assert_eq!(msg, plain) 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /gm-sm2/src/u256.rs: -------------------------------------------------------------------------------- 1 | use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; 2 | use std::io::Cursor; 3 | 4 | pub type U256 = [u64; 4]; 5 | pub type U512 = [u64; 8]; 6 | 7 | pub(crate) const SM2_ZERO: U256 = [0, 0, 0, 0]; 8 | pub(crate) const SM2_ONE: U256 = [1, 0, 0, 0]; 9 | 10 | #[inline(always)] 11 | pub const fn u256_add(a: &U256, b: &U256) -> (U256, bool) { 12 | let mut sum = [0; 4]; 13 | let mut carry = false; 14 | let mut i = 0; 15 | loop { 16 | let (t_sum, c) = { 17 | let (m, c1) = a[i].overflowing_add(b[i]); 18 | let (r, c2) = m.overflowing_add(carry as u64); 19 | (r, c1 || c2) 20 | }; 21 | sum[i] = t_sum; 22 | carry = c; 23 | if i == 3 { 24 | break; 25 | } 26 | i += 1; 27 | } 28 | (sum, carry) 29 | } 30 | 31 | #[inline(always)] 32 | pub const fn u512_add(a: &U512, b: &U512) -> (U512, bool) { 33 | let mut sum = [0; 8]; 34 | let mut carry = false; 35 | let mut i = 0; 36 | loop { 37 | let (t_sum, c) = { 38 | let (m, c1) = a[i].overflowing_add(b[i]); 39 | let (r, c2) = m.overflowing_add(carry as u64); 40 | (r, c1 || c2) 41 | }; 42 | sum[i] = t_sum; 43 | carry = c; 44 | if i == 7 { 45 | break; 46 | } 47 | i += 1; 48 | } 49 | (sum, carry) 50 | } 51 | 52 | #[inline(always)] 53 | pub const fn u256_sub(a: &U256, b: &U256) -> (U256, bool) { 54 | let mut r = [0; 4]; 55 | let mut borrow = false; 56 | let mut j = 3; 57 | loop { 58 | let i = 3 - j; 59 | let (diff, bor) = { 60 | let (a, b1) = a[i].overflowing_sub(borrow as u64); 61 | let (res, b2) = a.overflowing_sub(b[i]); 62 | (res, b1 || b2) 63 | }; 64 | r[i] = diff; 65 | borrow = bor; 66 | if j == 0 { 67 | break; 68 | } 69 | j -= 1; 70 | } 71 | (r, borrow) 72 | } 73 | 74 | #[inline(always)] 75 | pub const fn u512_sub(a: &U512, b: &U512) -> (U512, bool) { 76 | let mut r = [0; 8]; 77 | let mut borrow = false; 78 | let mut j = 7; 79 | loop { 80 | let i = 7 - j; 81 | let (diff, bor) = { 82 | let (a, b1) = a[i].overflowing_sub(borrow as u64); 83 | let (res, b2) = a.overflowing_sub(b[i]); 84 | (res, b1 || b2) 85 | }; 86 | r[i] = diff; 87 | borrow = bor; 88 | if j == 0 { 89 | break; 90 | } 91 | j -= 1; 92 | } 93 | (r, borrow) 94 | } 95 | 96 | pub fn u256_bits_and(a: &U256, b: &U256) -> U256 { 97 | let mut result: [u64; 4] = [0; 4]; 98 | for i in 0..a.len() { 99 | result[i] = a[i] & b[i]; 100 | } 101 | result 102 | } 103 | 104 | #[inline(always)] 105 | pub fn u256_mul(a: &U256, b: &U256) -> U512 { 106 | let mut a_: [u64; 8] = [0; 8]; 107 | let mut b_: [u64; 8] = [0; 8]; 108 | let mut ret: [u64; 8] = [0; 8]; 109 | let mut s: [u64; 16] = [0; 16]; 110 | 111 | for i in 0..4 { 112 | a_[2 * i] = a[i] & 0xffffffff; 113 | b_[2 * i] = b[i] & 0xffffffff; 114 | a_[2 * i + 1] = a[i] >> 32; 115 | b_[2 * i + 1] = b[i] >> 32; 116 | } 117 | 118 | let mut u = 0; 119 | for i in 0..8 { 120 | u = 0; 121 | for j in 0..8 { 122 | u = s[i + j] + a_[i] * b_[j] + u; 123 | s[i + j] = u & 0xffffffff; 124 | u >>= 32; 125 | } 126 | s[i + 8] = u; 127 | } 128 | 129 | for i in 0..8 { 130 | ret[i] = (s[2 * i + 1] << 32) | s[2 * i]; 131 | } 132 | ret 133 | } 134 | 135 | #[inline(always)] 136 | pub const fn u256_cmp(a: &U256, b: &U256) -> i32 { 137 | if a[3] > b[3] { 138 | return 1; 139 | } 140 | if a[3] < b[3] { 141 | return -1; 142 | } 143 | if a[2] > b[2] { 144 | return 1; 145 | } 146 | if a[2] < b[2] { 147 | return -1; 148 | } 149 | if a[1] > b[1] { 150 | return 1; 151 | } 152 | if a[1] < b[1] { 153 | return -1; 154 | } 155 | if a[0] > b[0] { 156 | return 1; 157 | } 158 | if a[0] < b[0] { 159 | return -1; 160 | } 161 | return 0; 162 | } 163 | 164 | #[inline(always)] 165 | pub fn u256_to_be_bytes(a: &U256) -> Vec { 166 | let mut ret: Vec = Vec::new(); 167 | for i in (0..4).rev() { 168 | ret.write_u64::(a[i]).unwrap(); 169 | } 170 | ret 171 | } 172 | 173 | #[inline(always)] 174 | pub fn u256_from_be_bytes(input: &[u8]) -> U256 { 175 | let mut elem = [0, 0, 0, 0]; 176 | let mut c = Cursor::new(input); 177 | for i in (0..4).rev() { 178 | elem[i] = c.read_u64::().unwrap(); 179 | } 180 | elem 181 | } 182 | 183 | #[cfg(test)] 184 | mod test_operation { 185 | use num_bigint::BigUint; 186 | 187 | use crate::u256::{u256_add, u256_mul, u256_sub}; 188 | 189 | #[test] 190 | fn test_raw_add_u64() { 191 | let a: [u64; 4] = [ 192 | 0x54806C11D8806141, 193 | 0xF1DD2C190F5E93C4, 194 | 0x597B6027B441A01F, 195 | 0x85AEF3D078640C98, 196 | ]; 197 | 198 | let b: [u64; 4] = [ 199 | 0x0E75C05FB4E3216D, 200 | 0x1006E85F5CDFF073, 201 | 0x1A7CE027B7A46F74, 202 | 0x41E00A53DDA532DA, 203 | ]; 204 | 205 | let a1 = BigUint::from_bytes_be( 206 | &hex::decode("85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141") 207 | .unwrap(), 208 | ); 209 | 210 | let b1 = BigUint::from_bytes_be( 211 | &hex::decode("41E00A53DDA532DA1A7CE027B7A46F741006E85F5CDFF0730E75C05FB4E3216D") 212 | .unwrap(), 213 | ); 214 | 215 | let (mut r, _c) = u256_add(&a, &b); 216 | r.reverse(); 217 | let mut sum = (&a1 + &b1).to_u64_digits(); 218 | sum.reverse(); 219 | assert_eq!(r, *sum); 220 | 221 | let (mut r, _c) = u256_sub(&a, &b); 222 | r.reverse(); 223 | let mut sub = (&a1 - &b1).to_u64_digits(); 224 | sub.reverse(); 225 | assert_eq!(r, *sub); 226 | 227 | let mut r = u256_mul(&a, &b); 228 | r.reverse(); 229 | let mut mul = (&a1 * &b1).to_u64_digits(); 230 | mul.reverse(); 231 | assert_eq!(r, *mul); 232 | } 233 | } 234 | -------------------------------------------------------------------------------- /gm-sm3/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("../README.md")] 2 | 3 | use std::fmt::{Display, Formatter}; 4 | use const_oid::ObjectIdentifier; 5 | 6 | 7 | pub const OID_SM3: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.156.10197.1.401"); 8 | 9 | pub enum Sm3Error { 10 | ErrorMsgLen, 11 | } 12 | 13 | impl std::fmt::Debug for Sm3Error { 14 | fn fmt(&self, f: &mut Formatter<'_>) -> ::std::fmt::Result { 15 | write!(f, "{}", self) 16 | } 17 | } 18 | 19 | impl From for &str { 20 | fn from(e: Sm3Error) -> Self { 21 | match e { 22 | Sm3Error::ErrorMsgLen => "SM3 Pad error: error msg len", 23 | } 24 | } 25 | } 26 | 27 | impl Display for Sm3Error { 28 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { 29 | let err_msg = match self { 30 | Sm3Error::ErrorMsgLen => "SM3 Pad error: error msg len", 31 | }; 32 | write!(f, "{}", err_msg) 33 | } 34 | } 35 | 36 | // 0 ≤ j ≤ 15 37 | pub(crate) const T00: u32 = 0x79cc4519; 38 | 39 | // 16 ≤ j ≤ 63 40 | pub(crate) const T16: u32 = 0x7a879d8a; 41 | 42 | pub(crate) static IV: [u32; 8] = [ 43 | 0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600, 0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e, 44 | ]; 45 | 46 | /// P0(X) = X ⊕ (X ≪ 9) ⊕ (X ≪ 17) 47 | fn p0(x: u32) -> u32 { 48 | x ^ x.rotate_left(9) ^ x.rotate_left(17) 49 | } 50 | 51 | /// P1(X) = X ⊕ (X ≪ 15) ⊕ (X ≪ 23) 52 | fn p1(x: u32) -> u32 { 53 | x ^ x.rotate_left(15) ^ x.rotate_left(23) 54 | } 55 | 56 | fn ff(x: u32, y: u32, z: u32, j: u32) -> u32 { 57 | if j <= 15 { 58 | return x ^ y ^ z; 59 | } else if j >= 16 && j <= 63 { 60 | return (x & y) | (x & z) | (y & z); 61 | } 62 | 0 63 | } 64 | 65 | fn gg(x: u32, y: u32, z: u32, j: u32) -> u32 { 66 | if j <= 15 { 67 | return x ^ y ^ z; 68 | } else if j >= 16 && j <= 63 { 69 | return (x & y) | (!x & z); 70 | } 71 | 0 72 | } 73 | 74 | fn t(j: usize) -> u32 { 75 | if j <= 15 { 76 | return T00; 77 | } else if j >= 16 && j <= 63 { 78 | return T16; 79 | } 80 | 0 81 | } 82 | 83 | /// # Example 84 | /// ```rust 85 | /// use crate::gm_sm3::sm3_hash; 86 | /// fn main(){ 87 | /// let hash = sm3_hash(b"abc"); 88 | /// let r = hex::encode(hash); 89 | /// assert_eq!("66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0", r); 90 | /// } 91 | /// 92 | /// ``` 93 | /// 94 | pub fn sm3_hash(msg: &[u8]) -> [u8; 32] { 95 | let msg = pad(msg).unwrap(); 96 | let len = msg.len(); 97 | let mut b_i: [u8; 64] = [0; 64]; 98 | let mut count_group: usize = 0; 99 | let mut v_i = IV; 100 | while count_group * 64 != len { 101 | for i in (count_group * 64)..(count_group * 64 + 64) { 102 | b_i[i - count_group * 64] = msg[i]; 103 | } 104 | cf(&mut v_i, b_i); 105 | count_group += 1; 106 | } 107 | let mut output: [u8; 32] = [0; 32]; 108 | for i in 0..8 { 109 | output[i * 4] = (v_i[i] >> 24) as u8; 110 | output[i * 4 + 1] = (v_i[i] >> 16) as u8; 111 | output[i * 4 + 2] = (v_i[i] >> 8) as u8; 112 | output[i * 4 + 3] = v_i[i] as u8; 113 | } 114 | output 115 | } 116 | 117 | fn cf(v_i: &mut [u32; 8], b_i: [u8; 64]) { 118 | // expend msg 119 | let mut w: [u32; 68] = [0; 68]; 120 | let mut w1: [u32; 64] = [0; 64]; 121 | 122 | // a. 将消息分组B(i)划分为16个字W0, W1, · · · , W15。 123 | let mut j = 0; 124 | while j <= 15 { 125 | w[j] = u32::from(b_i[j * 4]) << 24 126 | | u32::from(b_i[j * 4 + 1]) << 16 127 | | u32::from(b_i[j * 4 + 2]) << 8 128 | | u32::from(b_i[j * 4 + 3]); 129 | j += 1; 130 | } 131 | 132 | // b. Wj ← P1(Wj−16 ⊕ Wj−9 ⊕ (Wj−3 ≪ 15)) ⊕ (Wj−13 ≪ 7) ⊕ Wj−6 133 | j = 16; 134 | while j <= 67 { 135 | w[j] = p1(w[j - 16] ^ w[j - 9] ^ w[j - 3].rotate_left(15)) 136 | ^ w[j - 13].rotate_left(7) 137 | ^ w[j - 6]; 138 | j += 1; 139 | } 140 | 141 | // c. Wj′ = Wj ⊕ Wj+4 142 | j = 0; 143 | while j <= 63 { 144 | w1[j] = w[j] ^ w[j + 4]; 145 | j += 1; 146 | } 147 | 148 | let mut a = v_i[0]; 149 | let mut b = v_i[1]; 150 | let mut c = v_i[2]; 151 | let mut d = v_i[3]; 152 | let mut e = v_i[4]; 153 | let mut f = v_i[5]; 154 | let mut g = v_i[6]; 155 | let mut h = v_i[7]; 156 | 157 | for j in 0..64 { 158 | let ss1 = (a 159 | .rotate_left(12) 160 | .wrapping_add(e) 161 | .wrapping_add(t(j).rotate_left(j as u32))) 162 | .rotate_left(7); 163 | let ss2 = ss1 ^ (a.rotate_left(12)); 164 | let tt1 = ff(a, b, c, j as u32) 165 | .wrapping_add(d) 166 | .wrapping_add(ss2) 167 | .wrapping_add(w1[j]); 168 | let tt2 = gg(e, f, g, j as u32) 169 | .wrapping_add(h) 170 | .wrapping_add(ss1) 171 | .wrapping_add(w[j]); 172 | d = c; 173 | c = b.rotate_left(9); 174 | b = a; 175 | a = tt1; 176 | h = g; 177 | g = f.rotate_left(19); 178 | f = e; 179 | e = p0(tt2); 180 | } 181 | v_i[0] ^= a; 182 | v_i[1] ^= b; 183 | v_i[2] ^= c; 184 | v_i[3] ^= d; 185 | v_i[4] ^= e; 186 | v_i[5] ^= f; 187 | v_i[6] ^= g; 188 | v_i[7] ^= h; 189 | } 190 | 191 | fn pad(msg: &[u8]) -> Result, Sm3Error> { 192 | let bit_length = (msg.len() << 3) as u64; 193 | let mut msg = msg.to_vec(); 194 | msg.push(0x80); 195 | let blocksize = 64; 196 | while msg.len() % blocksize != 56 { 197 | msg.push(0x00); 198 | } 199 | msg.push((bit_length >> 56 & 0xff) as u8); 200 | msg.push((bit_length >> 48 & 0xff) as u8); 201 | msg.push((bit_length >> 40 & 0xff) as u8); 202 | msg.push((bit_length >> 32 & 0xff) as u8); 203 | msg.push((bit_length >> 24 & 0xff) as u8); 204 | msg.push((bit_length >> 16 & 0xff) as u8); 205 | msg.push((bit_length >> 8 & 0xff) as u8); 206 | msg.push((bit_length & 0xff) as u8); 207 | if msg.len() % 64 != 0 { 208 | return Err(Sm3Error::ErrorMsgLen); 209 | } 210 | Ok(msg) 211 | } 212 | 213 | #[cfg(test)] 214 | mod test { 215 | use crate::*; 216 | 217 | #[test] 218 | fn test_hash_1() { 219 | let hash = sm3_hash(b"abc"); 220 | let r = hex::encode(hash); 221 | assert_eq!( 222 | "66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0", 223 | r 224 | ); 225 | } 226 | 227 | #[test] 228 | fn test_hash_2() { 229 | let hash = sm3_hash(b"abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"); 230 | let r = hex::encode(hash); 231 | assert_eq!( 232 | "debe9ff92275b8a138604889c18e5a4d6fdb70e5387e5765293dcba39c0c5732", 233 | r 234 | ); 235 | } 236 | } 237 | -------------------------------------------------------------------------------- /gm-sm2/src/fields/fp64.rs: -------------------------------------------------------------------------------- 1 | use rand::RngCore; 2 | 3 | use crate::error::{Sm2Error, Sm2Result}; 4 | use crate::fields::FieldModOperation; 5 | use crate::u256::{ 6 | SM2_ONE, SM2_ZERO, U256, u256_add, u256_cmp, u256_from_be_bytes, u256_mul, 7 | u256_sub, u256_to_be_bytes, u512_add, 8 | }; 9 | 10 | // 0xfffffffeffffffffffffffffffffffffffffffff00000000ffffffffffffffff 11 | pub const SM2_P: U256 = [ 12 | 0xffffffffffffffff, 13 | 0xffffffff00000000, 14 | 0xffffffffffffffff, 15 | 0xfffffffeffffffff, 16 | ]; 17 | 18 | pub const SM2_P_MINUS_ONE: U256 = [ 19 | 0xfffffffffffffffe, 20 | 0xffffffff00000000, 21 | 0xffffffffffffffff, 22 | 0xfffffffeffffffff, 23 | ]; 24 | 25 | pub const SM2_P_MINUS_TWO: U256 = [ 26 | 0xfffffffffffffffd, 27 | 0xffffffff00000000, 28 | 0xffffffffffffffff, 29 | 0xfffffffeffffffff, 30 | ]; 31 | 32 | // p' = -p^(-1) mod 2^256 33 | // = fffffffc00000001fffffffe00000000ffffffff000000010000000000000001 34 | // sage: -(IntegerModRing(2^256)(p))^-1 35 | pub const SM2_P_PRIME: U256 = [ 36 | 0x0000000000000001, 37 | 0xffffffff00000001, 38 | 0xfffffffe00000000, 39 | 0xfffffffc00000001, 40 | ]; 41 | 42 | // 2^512 (mod p) 43 | pub const SM2_MODP_2E512: U256 = [ 44 | 0x0000000200000003, 45 | 0x00000002ffffffff, 46 | 0x0000000100000001, 47 | 0x0000000400000002, 48 | ]; 49 | 50 | // (p+1)/4 = 3fffffffbfffffffffffffffffffffffffffffffc00000004000000000000000 51 | pub const SM2_SQRT_EXP: U256 = [ 52 | 0x4000000000000000, 53 | 0xffffffffc0000000, 54 | 0xffffffffffffffff, 55 | 0x3fffffffbfffffff, 56 | ]; 57 | 58 | pub const SM2_MODP_MONT_ONE: U256 = [1, (1 << 32) - 1, 0, 1 << 32]; 59 | 60 | // mont(b), b = 0x28e9fa9e9d9f5e344d5a9e4bcf6509a7f39789f515ab8f92ddbcbd414d940e93 61 | pub const SM2_MODP_MONT_B: U256 = [ 62 | 0x90d230632bc0dd42, 63 | 0x71cf379ae9b537ab, 64 | 0x527981505ea51c3c, 65 | 0x240fe188ba20e2c8, 66 | ]; 67 | 68 | pub const SM2_MODP_MONT_A: U256 = [ 69 | 0xfffffffffffffffc, 70 | 0xfffffffc00000003, 71 | 0xffffffffffffffff, 72 | 0xfffffffbffffffff, 73 | ]; 74 | 75 | // 0x32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7 76 | pub const SM2_G_X: U256 = [ 77 | 0x715a4589334c74c7, 78 | 0x8fe30bbff2660be1, 79 | 0x5f9904466a39c994, 80 | 0x32c4ae2c1f198119, 81 | ]; 82 | 83 | // 0xbc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0 84 | pub const SM2_G_Y: U256 = [ 85 | 0x02df32e52139f0a0, 86 | 0xd0a9877cc62a4740, 87 | 0x59bdcee36b692153, 88 | 0xbc3736a2f4f6779c, 89 | ]; 90 | 91 | #[inline(always)] 92 | pub fn random_u256() -> U256 { 93 | let mut rng = rand::thread_rng(); 94 | let mut buf: [u8; 32] = [0; 32]; 95 | let mut ret; 96 | loop { 97 | rng.fill_bytes(&mut buf[..]); 98 | ret = u256_from_be_bytes(&buf); 99 | if u256_cmp(&ret, &SM2_P_MINUS_ONE) < 0 && ret != [0, 0, 0, 0] { 100 | break; 101 | } 102 | } 103 | ret 104 | } 105 | 106 | pub fn fp_pow(a: &U256, e: &U256) -> U256 { 107 | let mut r = SM2_MODP_MONT_ONE; 108 | let mut w = 0u64; 109 | for i in (0..4).rev() { 110 | w = e[i]; 111 | for _j in 0..64 { 112 | r = r.fp_sqr(); 113 | if w & 0x8000000000000000 != 0 { 114 | r = r.fp_mul(a); 115 | } 116 | w <<= 1; 117 | } 118 | } 119 | r 120 | } 121 | 122 | pub(crate) fn fp_to_mont(a: &U256) -> U256 { 123 | mont_mul(a, &SM2_MODP_2E512) 124 | } 125 | 126 | pub(crate) fn fp_from_mont(a: &U256) -> U256 { 127 | mont_mul(a, &SM2_ONE) 128 | } 129 | 130 | pub(crate) fn mont_mul(a: &U256, b: &U256) -> U256 { 131 | let mut r = [0u64; 4]; 132 | 133 | let mut z = [0u64; 8]; 134 | let mut t = [0u64; 8]; 135 | 136 | // z = a * b 137 | z = u256_mul(a, b); 138 | 139 | // t = low(z) * p' 140 | let z_low = [z[0], z[1], z[2], z[3]]; 141 | let t1 = u256_mul(&z_low, &SM2_P_PRIME); 142 | t[0] = t1[0]; 143 | t[1] = t1[1]; 144 | t[2] = t1[2]; 145 | t[3] = t1[3]; 146 | 147 | // t = low(t) * p 148 | let t_low = [t[0], t[1], t[2], t[3]]; 149 | t = u256_mul(&t_low, &SM2_P); 150 | 151 | // z = z + t 152 | let (sum, c) = u512_add(&z, &t); 153 | z = sum; 154 | 155 | // r = high(z) 156 | r = [z[4], z[5], z[6], z[7]]; 157 | if c { 158 | r = u256_add(&r, &SM2_MODP_MONT_ONE).0; 159 | } else if u256_cmp(&r, &SM2_P) >= 0 { 160 | r = u256_sub(&r, &SM2_P).0 161 | } 162 | r 163 | } 164 | 165 | pub fn fp_sqrt(a: &U256) -> Sm2Result { 166 | let r = fp_pow(a, &SM2_SQRT_EXP); 167 | let a1 = r.fp_sqr(); 168 | if u256_cmp(&a1, &a) != 0 { 169 | return Err(Sm2Error::FieldSqrtError); 170 | } 171 | Ok(r) 172 | } 173 | 174 | impl FieldModOperation for U256 { 175 | fn zero() -> Self { 176 | SM2_ZERO 177 | } 178 | 179 | fn one() -> Self { 180 | SM2_ONE 181 | } 182 | 183 | fn is_zero(&self) -> bool { 184 | self == &SM2_ZERO 185 | } 186 | 187 | fn fp_sqr(&self) -> Self { 188 | self.fp_mul(self) 189 | } 190 | 191 | fn fp_double(&self) -> Self { 192 | self.fp_add(self) 193 | } 194 | 195 | fn fp_triple(&self) -> Self { 196 | let mut r = self.fp_double(); 197 | r = self.fp_add(&r); 198 | r 199 | } 200 | 201 | fn fp_add(&self, rhs: &Self) -> Self { 202 | let (r, c) = u256_add(self, rhs); 203 | if c { 204 | let (diff, _borrow) = u256_add(&r, &SM2_MODP_MONT_ONE); 205 | return diff; 206 | } 207 | if u256_cmp(&r, &SM2_P) >= 0 { 208 | let (diff, _borrow) = u256_sub(&r, &SM2_P); 209 | return diff; 210 | } 211 | r 212 | } 213 | 214 | fn fp_sub(&self, rhs: &Self) -> Self { 215 | let (raw_diff, borrow) = u256_sub(self, rhs); 216 | if borrow { 217 | let (diff, _borrow) = u256_sub(&raw_diff, &SM2_MODP_MONT_ONE); 218 | diff 219 | } else { 220 | raw_diff 221 | } 222 | } 223 | 224 | fn fp_mul(&self, rhs: &Self) -> Self { 225 | mont_mul(self, rhs) 226 | } 227 | 228 | fn fp_neg(&self) -> Self { 229 | if self.is_zero() { 230 | self.clone() 231 | } else { 232 | u256_sub(&SM2_P, self).0 233 | } 234 | } 235 | 236 | fn fp_div2(&self) -> Self { 237 | let mut r = self.clone(); 238 | let mut c = 0; 239 | if r[0] & 0x01 == 1 { 240 | r = self.fp_add(&SM2_P); 241 | c = u64::from(u256_add(&self, &SM2_P).1) 242 | } else { 243 | r[0] = self[0]; 244 | r[1] = self[1]; 245 | r[2] = self[2]; 246 | r[3] = self[3]; 247 | } 248 | r[0] = (r[0] >> 1) | ((r[1] & 1) << 63); 249 | r[1] = (r[1] >> 1) | ((r[2] & 1) << 63); 250 | r[2] = (r[2] >> 1) | ((r[3] & 1) << 63); 251 | r[3] = (r[3] >> 1) | ((c & 1) << 63); 252 | r 253 | } 254 | 255 | fn fp_inv(&self) -> Self { 256 | fp_pow(self, &SM2_P_MINUS_TWO) 257 | } 258 | 259 | fn to_byte_be(&self) -> Vec { 260 | u256_to_be_bytes(self) 261 | } 262 | 263 | fn from_byte_be(input: &[u8]) -> Self { 264 | u256_from_be_bytes(input) 265 | } 266 | } 267 | -------------------------------------------------------------------------------- /gm-sm9/src/fields/fp.rs: -------------------------------------------------------------------------------- 1 | use rand::RngCore; 2 | 3 | use crate::fields::FieldElement; 4 | use crate::u256::{ 5 | u256_add, u256_cmp, u256_from_be_bytes, u256_mul, u256_sub, u256_to_be_bytes, u512_add, 6 | SM9_ONE, SM9_ZERO, U256, 7 | }; 8 | use crate::{ 9 | SM9_MODP_2E512, SM9_MODP_MONT_ONE, SM9_P, SM9_P_MINUS_ONE, SM9_P_MINUS_TWO, SM9_P_PRIME, 10 | }; 11 | 12 | pub type Fp = U256; 13 | 14 | #[inline(always)] 15 | pub fn fp_random_u256() -> U256 { 16 | let mut rng = rand::thread_rng(); 17 | let mut buf: [u8; 32] = [0; 32]; 18 | let mut ret; 19 | loop { 20 | rng.fill_bytes(&mut buf[..]); 21 | ret = u256_from_be_bytes(&buf); 22 | if u256_cmp(&ret, &SM9_P_MINUS_ONE) < 0 && ret != [0, 0, 0, 0] { 23 | break; 24 | } 25 | } 26 | ret 27 | } 28 | 29 | pub(crate) fn fp_pow(a: &Fp, e: &U256) -> Fp { 30 | let mut r = SM9_MODP_MONT_ONE; 31 | let mut w = 0u64; 32 | for i in (0..4).rev() { 33 | w = e[i]; 34 | for j in 0..64 { 35 | r = r.fp_sqr(); 36 | if w & 0x8000000000000000 != 0 { 37 | r = r.fp_mul(a); 38 | } 39 | w <<= 1; 40 | } 41 | } 42 | r 43 | } 44 | 45 | pub fn fp_to_mont(a: &Fp) -> Fp { 46 | mont_mul(a, &SM9_MODP_2E512) 47 | } 48 | 49 | pub fn fp_from_mont(a: &Fp) -> Fp { 50 | mont_mul(a, &SM9_ONE) 51 | } 52 | 53 | pub(crate) fn fp_from_bytes(buf: &[u8]) -> Fp { 54 | let mut t = u256_from_be_bytes(buf); 55 | t = fp_to_mont(&t); 56 | t 57 | } 58 | 59 | pub fn mont_mul(a: &Fp, b: &Fp) -> Fp { 60 | let mut r = [0u64; 4]; 61 | 62 | let mut t = [0u64; 8]; 63 | 64 | // z = a * b 65 | let mut z = u256_mul(a, b); 66 | 67 | // t = low(z) * p' 68 | let z_low = [z[0], z[1], z[2], z[3]]; 69 | let t1 = u256_mul(&z_low, &SM9_P_PRIME); 70 | t[0] = t1[0]; 71 | t[1] = t1[1]; 72 | t[2] = t1[2]; 73 | t[3] = t1[3]; 74 | 75 | // t = low(t) * p 76 | let t_low = [t[0], t[1], t[2], t[3]]; 77 | t = u256_mul(&t_low, &SM9_P); 78 | 79 | // z = z + t 80 | let (sum, c) = u512_add(&z, &t); 81 | z = sum; 82 | 83 | // r = high(z) 84 | r = [z[4], z[5], z[6], z[7]]; 85 | if c { 86 | r = u256_add(&r, &SM9_MODP_MONT_ONE).0; 87 | } else if u256_cmp(&r, &SM9_P) >= 0 { 88 | r = u256_sub(&r, &SM9_P).0 89 | } 90 | r 91 | } 92 | 93 | impl FieldElement for Fp { 94 | fn zero() -> Self { 95 | SM9_ZERO 96 | } 97 | 98 | fn one() -> Self { 99 | SM9_MODP_MONT_ONE 100 | } 101 | 102 | fn is_zero(&self) -> bool { 103 | self == &SM9_ZERO 104 | } 105 | 106 | fn fp_sqr(&self) -> Self { 107 | self.fp_mul(self) 108 | } 109 | 110 | fn fp_double(&self) -> Self { 111 | self.fp_add(self) 112 | } 113 | 114 | fn fp_triple(&self) -> Self { 115 | self.fp_double().fp_add(self) 116 | } 117 | 118 | fn fp_add(&self, rhs: &Self) -> Self { 119 | let (r, c) = u256_add(self, rhs); 120 | if c { 121 | let (diff, _borrow) = u256_add(&r, &SM9_MODP_MONT_ONE); 122 | return diff; 123 | } 124 | if u256_cmp(&r, &SM9_P) >= 0 { 125 | let (diff, _borrow) = u256_sub(&r, &SM9_P); 126 | return diff; 127 | } 128 | r 129 | } 130 | 131 | fn fp_sub(&self, rhs: &Self) -> Self { 132 | let (raw_diff, borrow) = u256_sub(&self, rhs); 133 | if borrow { 134 | let (diff, _borrow) = u256_sub(&raw_diff, &SM9_MODP_MONT_ONE); 135 | diff 136 | } else { 137 | raw_diff 138 | } 139 | } 140 | 141 | fn fp_mul(&self, rhs: &Self) -> Self { 142 | mont_mul(self, rhs) 143 | } 144 | 145 | fn fp_neg(&self) -> Self { 146 | if self.is_zero() { 147 | self.clone() 148 | } else { 149 | u256_sub(&SM9_P, self).0 150 | } 151 | } 152 | 153 | fn fp_div2(&self) -> Self { 154 | let mut r = self.clone(); 155 | let mut c = 0; 156 | if r[0] & 0x01 == 1 { 157 | let (sum, carry) = u256_add(self, &SM9_P); 158 | c = carry as u64; 159 | r = sum; 160 | } else { 161 | r[0] = self[0]; 162 | r[1] = self[1]; 163 | r[2] = self[2]; 164 | r[3] = self[3]; 165 | } 166 | r[0] = (r[0] >> 1) | ((r[1] & 1) << 63); 167 | r[1] = (r[1] >> 1) | ((r[2] & 1) << 63); 168 | r[2] = (r[2] >> 1) | ((r[3] & 1) << 63); 169 | r[3] = (r[3] >> 1) | ((c & 1) << 63); 170 | r 171 | } 172 | 173 | fn fp_inv(&self) -> Self { 174 | fp_pow(self, &SM9_P_MINUS_TWO) 175 | } 176 | 177 | fn to_bytes_be(&self) -> Vec { 178 | let z = fp_from_mont(self); 179 | u256_to_be_bytes(&z) 180 | } 181 | } 182 | 183 | pub fn fp_from_hex(hex: &str) -> Fp { 184 | fp_to_mont(&u256_from_be_bytes(&hex::decode(hex).unwrap())) 185 | } 186 | 187 | #[cfg(test)] 188 | mod test_mod_operation { 189 | use crate::fields::fp::{fp_from_mont, fp_pow, fp_to_mont}; 190 | use crate::fields::FieldElement; 191 | 192 | #[test] 193 | fn test_mod_op() { 194 | let mut a: [u64; 4] = [ 195 | 0x54806C11D8806141, 196 | 0xF1DD2C190F5E93C4, 197 | 0x597B6027B441A01F, 198 | 0x85AEF3D078640C98, 199 | ]; 200 | 201 | let mut b: [u64; 4] = [ 202 | 0x0E75C05FB4E3216D, 203 | 0x1006E85F5CDFF073, 204 | 0x1A7CE027B7A46F74, 205 | 0x41E00A53DDA532DA, 206 | ]; 207 | 208 | let r = a.fp_add(&b); 209 | println!("fp_add ={:?}", &r); // [9045076647192182065, 16136820971490481499, 11381885983195088974, 1247213578799650944] 210 | 211 | let mut r = a.fp_sub(&b); 212 | r.reverse(); 213 | println!("fp_sub ={:x?}", r); // 43cee97c9abed9be3efe7ffffc9d30abe1d643b9b27ea351460aabb2239d3fd4 214 | 215 | a = fp_to_mont(&a); 216 | b = fp_to_mont(&b); 217 | let mut r = a.fp_mul(&b); 218 | r = fp_from_mont(&r); 219 | r.reverse(); 220 | println!("fp_mul ={:x?}", r); // 9e4d19bb5d94a47352e6f53f4116b2a71b16a1113dc789b26528ee19f46b72e0 221 | 222 | let mut r = a.fp_double(); 223 | r = fp_from_mont(&r); 224 | r.reverse(); 225 | println!("fp_dbl ={:x?}", r); // 551de7a0ee24723edcf314ff72f478fac1c7c4e7044238acc3913cfbcdaf7d05 226 | 227 | let mut r = a.fp_triple(); 228 | r = fp_from_mont(&r); 229 | r.reverse(); 230 | println!("fp_tri ={:x?}", r); // 248cdb7163e4d7e5606ac9d731a751d591b25db4f925dd9532a20de5c2de98c9 231 | 232 | let mut r = a.fp_div2(); 233 | r = fp_from_mont(&r); 234 | r.reverse(); 235 | println!("fp_div2 ={:x?}", r); // 9df779e83d83d9c517bf85bbd4e833b289e7dfb214ecc1501cf8039cdde8d35f 236 | 237 | let mut r = a.fp_neg(); 238 | r = fp_from_mont(&r); 239 | r.reverse(); 240 | println!("fp_neg ={:x?}", r); // 30910c2f8a3f9a597c884b28414d2725301567320b1c5b1790ef2f160ad0e43c 241 | 242 | let mut r = a.fp_sqr(); 243 | r = fp_from_mont(&r); 244 | r.reverse(); 245 | println!("fp_sqr ={:x?}", r); // 46dc2a5b8853234b341d9c57f9c4ca5709e95bbfef25356812e884e4f38cd0d6 246 | 247 | b = fp_from_mont(&b); 248 | let mut r = fp_pow(&a, &b); 249 | r = fp_from_mont(&r); 250 | r.reverse(); 251 | println!("fp_pow ={:x?}", r); 252 | 253 | let mut r = a.fp_inv(); 254 | r = fp_from_mont(&r); 255 | r.reverse(); 256 | println!("fp_inv ={:x?}", r); 257 | } 258 | } 259 | -------------------------------------------------------------------------------- /gm-sm2/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("../README.md")] 2 | 3 | use pkcs8::ObjectIdentifier; 4 | use pkcs8::spki::AlgorithmIdentifier; 5 | 6 | pub mod error; 7 | pub mod exchange; 8 | pub mod key; 9 | pub mod p256_ecc; 10 | pub mod util; 11 | pub mod pkcs; 12 | pub mod u256; 13 | pub(crate) mod fields; 14 | pub(crate) mod sm2p256_table; 15 | 16 | /// Fp 的加法,减法,乘法并不是简单的四则运算。其运算结果的值必须在Fp的有限域中,这样保证椭圆曲线变成离散的点 17 | /// 18 | /// 这里我们规定一个有限域Fp 19 | /// 20 | /// * 取大质数p,则有限域中有p-1个有限元:0,1,2...p-1 21 | /// * Fp上的加法为模p加法`a+b≡c(mod p)` 22 | /// * Fp上的乘法为模p乘法`a×b≡c(mod p)` 23 | /// * Fp上的减法为模p减法`a-b≡c(mod p)` 24 | /// * Fp上的除法就是乘除数的乘法逆元`a÷b≡c(mod p)`,即 `a×b^(-1)≡c (mod p)` 25 | /// * Fp的乘法单位元为1,零元为0 26 | /// * Fp域上满足交换律,结合律,分配律 27 | pub trait FeOperation { 28 | /// Returns `(self + other) % modulus`. 29 | /// 30 | /// Panics if the modulus is zero. 31 | /// 32 | fn mod_add(&self, other: &Self, modulus: &Self) -> Self; 33 | 34 | /// Returns `(self - other) % modulus`. 35 | /// 36 | /// Panics if the modulus is zero. 37 | /// 38 | fn mod_sub(&self, other: &Self, modulus: &Self) -> Self; 39 | 40 | /// Returns `(self * other) % modulus`. 41 | /// 42 | /// Panics if the modulus is zero. 43 | /// 44 | fn mod_mul(&self, other: &Self, modulus: &Self) -> Self; 45 | 46 | /// Extended Eulidean Algorithm(EEA) to calculate x^(-1) mod p 47 | fn inv(&self, modulus: &Self) -> Self; 48 | 49 | /// Self >>= carry 50 | fn right_shift(&self, carry: u32) -> Self; 51 | } 52 | 53 | /// oid to pkcs8 54 | pub const OID_SM2_PKCS8: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.156.10197.1.301"); 55 | pub const ALGORITHM_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10045.2.1"); 56 | 57 | const ALGORITHM_IDENTIFIER: AlgorithmIdentifier = AlgorithmIdentifier { 58 | oid: ALGORITHM_OID, 59 | parameters: Some(OID_SM2_PKCS8), 60 | }; 61 | 62 | /// oid refer to GM/T 0006 63 | pub const OID_SM2_CMS_1: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.156.10197.1.301.1"); 64 | pub const OID_SM2_CMS_3: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.156.10197.1.301.3"); 65 | 66 | /// oid refer to GM/T 0010 pkcs#7 67 | pub const OID_SM2_CMS_DATA: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.156.10197.6.1.4.2.1"); 68 | pub const OID_SM2_CMS_SIGNED: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.156.10197.6.1.4.2.2"); 69 | pub const OID_SM2_CMS_ENVELOPED: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.156.10197.6.1.4.2.3"); 70 | pub const OID_SM2_CMS_SIGNED_AND_ENVELOPED: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.156.10197.6.1.4.2.4"); 71 | pub const OID_SM2_CMS_ENCRYPTED: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.156.10197.6.1.4.2.5"); 72 | pub const OID_SM2_CMS_KEY_AGREEMENT_INFO: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.156.10197.6.1.4.2.6"); 73 | 74 | #[cfg(test)] 75 | mod test_sm2 { 76 | use crate::exchange; 77 | use crate::key::{gen_keypair, Sm2Model, Sm2PrivateKey, Sm2PublicKey}; 78 | 79 | #[test] 80 | fn test_encrypt_decrypt_with_gen_key() { 81 | let (pk, sk) = gen_keypair().unwrap(); 82 | let msg = vec![00, 0, 100, 0, 134]; 83 | // let msg = "你好 hello world".as_bytes(); 84 | let encrypt = pk.encrypt(&msg, false, Sm2Model::C1C2C3).unwrap(); 85 | let plain = sk.decrypt(&encrypt, false, Sm2Model::C1C2C3).unwrap(); 86 | println!("public key {}", pk.to_hex_string(false)); 87 | println!("private key {}", sk.to_hex_string()); 88 | assert_eq!(msg, plain) 89 | } 90 | 91 | #[test] 92 | fn test_encrypt_decrypt_with_special_key() { 93 | let public_key = "048626c62a8582c639cb3c87b59118713a519988c5f6497f91dd672abbdaaed0420ea7bc2cd03a7c938adc42b450549d312bec823b74cf22cf57c63cebd011c595"; 94 | let private_key = "eb20009ffbffc90aeeb288ca7d782c722332d1d16a206cafec7dd6c64e6fc525"; 95 | let pk = Sm2PublicKey::from_hex_string(public_key).unwrap(); 96 | let sk = Sm2PrivateKey::from_hex_string(private_key).unwrap(); 97 | 98 | let msg = "你好 world,asjdkajhdjadahkubbhj12893718927391873891,@@!! world,1231 wo12321321313asdadadahello world,hello world".as_bytes(); 99 | let encrypt = pk.encrypt(msg, false, Sm2Model::C1C3C2).unwrap(); 100 | let plain = sk.decrypt(&encrypt, false, Sm2Model::C1C3C2).unwrap(); 101 | assert_eq!(msg, plain); 102 | } 103 | 104 | #[test] 105 | fn test_encrypt_decrypt_with_java_bouncycastle_gen_key() { 106 | let public_key = "046a6ff781355cc1a9e538213f3a2074ceb32eae9e1caa090e74bbac9024cd58969619ec8dd797635773a9e8c3401135687a49381bb088d4f10c8feed899bf69c5"; 107 | let private_key = "ff88f12d6f28a852cc59ace674efb842163f1c5294890be9843fe5c20e26a011"; 108 | let pk = Sm2PublicKey::from_hex_string(public_key).unwrap(); 109 | let sk = Sm2PrivateKey::from_hex_string(private_key).unwrap(); 110 | 111 | let msg = "你好 world,asjdkajhdjadahkubbhj12893718927391873891,@@!! world,1231 wo12321321313asdadadahello world,hello world".as_bytes(); 112 | let encrypt = pk.encrypt(msg, false, Sm2Model::C1C3C2).unwrap(); 113 | let plain = sk.decrypt(&encrypt, false, Sm2Model::C1C3C2).unwrap(); 114 | assert_eq!(msg, plain); 115 | } 116 | 117 | #[test] 118 | fn test_sign_verify() { 119 | let msg = b"hello"; 120 | let (pk, sk) = gen_keypair().unwrap(); 121 | let signature = sk.sign(None, msg).unwrap(); 122 | pk.verify(None, msg, &signature).unwrap(); 123 | } 124 | 125 | #[test] 126 | fn test_sign_verify_with_special_key() { 127 | let msg = b"hello world"; 128 | let public_key = "048626c62a8582c639cb3c87b59118713a519988c5f6497f91dd672abbdaaed0420ea7bc2cd03a7c938adc42b450549d312bec823b74cf22cf57c63cebd011c595"; 129 | let private_key = "eb20009ffbffc90aeeb288ca7d782c722332d1d16a206cafec7dd6c64e6fc525"; 130 | let pk = Sm2PublicKey::from_hex_string(public_key).unwrap(); 131 | let sk = Sm2PrivateKey::from_hex_string(private_key).unwrap(); 132 | let signature = sk.sign(None, msg).unwrap(); 133 | println!("r = {:?}", &signature[..32]); 134 | println!("s = {:?}", &signature[32..]); 135 | pk.verify(None, msg, &signature).unwrap(); 136 | } 137 | 138 | #[test] 139 | fn test_sign_verify_with_java_bouncycastle_gen_key() { 140 | let msg = "hello,你好".as_bytes(); 141 | let public_key = "046a6ff781355cc1a9e538213f3a2074ceb32eae9e1caa090e74bbac9024cd58969619ec8dd797635773a9e8c3401135687a49381bb088d4f10c8feed899bf69c5"; 142 | let private_key = "ff88f12d6f28a852cc59ace674efb842163f1c5294890be9843fe5c20e26a011"; 143 | let pk = Sm2PublicKey::from_hex_string(public_key).unwrap(); 144 | let sk = Sm2PrivateKey::from_hex_string(private_key).unwrap(); 145 | let signature = sk.sign(None, msg).unwrap(); 146 | pk.verify(None, msg, &signature).unwrap(); 147 | } 148 | 149 | #[test] 150 | fn test_key_exchange() { 151 | let id_a = "alice123@qq.com"; 152 | let id_b = "bob456@qq.com"; 153 | 154 | let (mut alice, mut bob) = exchange::build_ex_pair(8, id_a, id_b).unwrap(); 155 | 156 | let ra_point = alice.exchange_1().unwrap(); 157 | let (rb_point, sb) = bob.exchange_2(&ra_point).unwrap(); 158 | let sa = alice.exchange_3(&rb_point, sb).unwrap(); 159 | let succ = bob.exchange_4(sa, &ra_point).unwrap(); 160 | assert_eq!(succ, true); 161 | assert_eq!(alice.k, bob.k); 162 | } 163 | 164 | 165 | #[test] 166 | fn test_encrypt_decrypt_asn1_with_special_key() { 167 | let public_key = "048626c62a8582c639cb3c87b59118713a519988c5f6497f91dd672abbdaaed0420ea7bc2cd03a7c938adc42b450549d312bec823b74cf22cf57c63cebd011c595"; 168 | let private_key = "eb20009ffbffc90aeeb288ca7d782c722332d1d16a206cafec7dd6c64e6fc525"; 169 | let pk = Sm2PublicKey::from_hex_string(public_key).unwrap(); 170 | let sk = Sm2PrivateKey::from_hex_string(private_key).unwrap(); 171 | 172 | let msg = "你好 world,asjdkajhdjadahkubbhj12893718927391873891,@@!! world,1231 wo12321321313asdadadahello world,hello world".as_bytes(); 173 | let encrypt = pk.encrypt_asn1(msg, false, Sm2Model::C1C3C2).unwrap(); 174 | let plain = sk.decrypt_asn1(&encrypt, false, Sm2Model::C1C3C2).unwrap(); 175 | assert_eq!(msg, plain); 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /gm-zuc/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("../README.md")] 2 | 3 | pub mod eea; 4 | pub mod eia; 5 | 6 | const S0: [u8; 256] = [ 7 | 0x3e, 0x72, 0x5b, 0x47, 0xca, 0xe0, 0x00, 0x33, 0x04, 0xd1, 0x54, 0x98, 0x09, 0xb9, 0x6d, 0xcb, 8 | 0x7b, 0x1b, 0xf9, 0x32, 0xaf, 0x9d, 0x6a, 0xa5, 0xb8, 0x2d, 0xfc, 0x1d, 0x08, 0x53, 0x03, 0x90, 9 | 0x4d, 0x4e, 0x84, 0x99, 0xe4, 0xce, 0xd9, 0x91, 0xdd, 0xb6, 0x85, 0x48, 0x8b, 0x29, 0x6e, 0xac, 10 | 0xcd, 0xc1, 0xf8, 0x1e, 0x73, 0x43, 0x69, 0xc6, 0xb5, 0xbd, 0xfd, 0x39, 0x63, 0x20, 0xd4, 0x38, 11 | 0x76, 0x7d, 0xb2, 0xa7, 0xcf, 0xed, 0x57, 0xc5, 0xf3, 0x2c, 0xbb, 0x14, 0x21, 0x06, 0x55, 0x9b, 12 | 0xe3, 0xef, 0x5e, 0x31, 0x4f, 0x7f, 0x5a, 0xa4, 0x0d, 0x82, 0x51, 0x49, 0x5f, 0xba, 0x58, 0x1c, 13 | 0x4a, 0x16, 0xd5, 0x17, 0xa8, 0x92, 0x24, 0x1f, 0x8c, 0xff, 0xd8, 0xae, 0x2e, 0x01, 0xd3, 0xad, 14 | 0x3b, 0x4b, 0xda, 0x46, 0xeb, 0xc9, 0xde, 0x9a, 0x8f, 0x87, 0xd7, 0x3a, 0x80, 0x6f, 0x2f, 0xc8, 15 | 0xb1, 0xb4, 0x37, 0xf7, 0x0a, 0x22, 0x13, 0x28, 0x7c, 0xcc, 0x3c, 0x89, 0xc7, 0xc3, 0x96, 0x56, 16 | 0x07, 0xbf, 0x7e, 0xf0, 0x0b, 0x2b, 0x97, 0x52, 0x35, 0x41, 0x79, 0x61, 0xa6, 0x4c, 0x10, 0xfe, 17 | 0xbc, 0x26, 0x95, 0x88, 0x8a, 0xb0, 0xa3, 0xfb, 0xc0, 0x18, 0x94, 0xf2, 0xe1, 0xe5, 0xe9, 0x5d, 18 | 0xd0, 0xdc, 0x11, 0x66, 0x64, 0x5c, 0xec, 0x59, 0x42, 0x75, 0x12, 0xf5, 0x74, 0x9c, 0xaa, 0x23, 19 | 0x0e, 0x86, 0xab, 0xbe, 0x2a, 0x02, 0xe7, 0x67, 0xe6, 0x44, 0xa2, 0x6c, 0xc2, 0x93, 0x9f, 0xf1, 20 | 0xf6, 0xfa, 0x36, 0xd2, 0x50, 0x68, 0x9e, 0x62, 0x71, 0x15, 0x3d, 0xd6, 0x40, 0xc4, 0xe2, 0x0f, 21 | 0x8e, 0x83, 0x77, 0x6b, 0x25, 0x05, 0x3f, 0x0c, 0x30, 0xea, 0x70, 0xb7, 0xa1, 0xe8, 0xa9, 0x65, 22 | 0x8d, 0x27, 0x1a, 0xdb, 0x81, 0xb3, 0xa0, 0xf4, 0x45, 0x7a, 0x19, 0xdf, 0xee, 0x78, 0x34, 0x60, 23 | ]; 24 | 25 | const S1: [u8; 256] = [ 26 | 0x55, 0xc2, 0x63, 0x71, 0x3b, 0xc8, 0x47, 0x86, 0x9f, 0x3c, 0xda, 0x5b, 0x29, 0xaa, 0xfd, 0x77, 27 | 0x8c, 0xc5, 0x94, 0x0c, 0xa6, 0x1a, 0x13, 0x00, 0xe3, 0xa8, 0x16, 0x72, 0x40, 0xf9, 0xf8, 0x42, 28 | 0x44, 0x26, 0x68, 0x96, 0x81, 0xd9, 0x45, 0x3e, 0x10, 0x76, 0xc6, 0xa7, 0x8b, 0x39, 0x43, 0xe1, 29 | 0x3a, 0xb5, 0x56, 0x2a, 0xc0, 0x6d, 0xb3, 0x05, 0x22, 0x66, 0xbf, 0xdc, 0x0b, 0xfa, 0x62, 0x48, 30 | 0xdd, 0x20, 0x11, 0x06, 0x36, 0xc9, 0xc1, 0xcf, 0xf6, 0x27, 0x52, 0xbb, 0x69, 0xf5, 0xd4, 0x87, 31 | 0x7f, 0x84, 0x4c, 0xd2, 0x9c, 0x57, 0xa4, 0xbc, 0x4f, 0x9a, 0xdf, 0xfe, 0xd6, 0x8d, 0x7a, 0xeb, 32 | 0x2b, 0x53, 0xd8, 0x5c, 0xa1, 0x14, 0x17, 0xfb, 0x23, 0xd5, 0x7d, 0x30, 0x67, 0x73, 0x08, 0x09, 33 | 0xee, 0xb7, 0x70, 0x3f, 0x61, 0xb2, 0x19, 0x8e, 0x4e, 0xe5, 0x4b, 0x93, 0x8f, 0x5d, 0xdb, 0xa9, 34 | 0xad, 0xf1, 0xae, 0x2e, 0xcb, 0x0d, 0xfc, 0xf4, 0x2d, 0x46, 0x6e, 0x1d, 0x97, 0xe8, 0xd1, 0xe9, 35 | 0x4d, 0x37, 0xa5, 0x75, 0x5e, 0x83, 0x9e, 0xab, 0x82, 0x9d, 0xb9, 0x1c, 0xe0, 0xcd, 0x49, 0x89, 36 | 0x01, 0xb6, 0xbd, 0x58, 0x24, 0xa2, 0x5f, 0x38, 0x78, 0x99, 0x15, 0x90, 0x50, 0xb8, 0x95, 0xe4, 37 | 0xd0, 0x91, 0xc7, 0xce, 0xed, 0x0f, 0xb4, 0x6f, 0xa0, 0xcc, 0xf0, 0x02, 0x4a, 0x79, 0xc3, 0xde, 38 | 0xa3, 0xef, 0xea, 0x51, 0xe6, 0x6b, 0x18, 0xec, 0x1b, 0x2c, 0x80, 0xf7, 0x74, 0xe7, 0xff, 0x21, 39 | 0x5a, 0x6a, 0x54, 0x1e, 0x41, 0x31, 0x92, 0x35, 0xc4, 0x33, 0x07, 0x0a, 0xba, 0x7e, 0x0e, 0x34, 40 | 0x88, 0xb1, 0x98, 0x7c, 0xf3, 0x3d, 0x60, 0x6c, 0x7b, 0xca, 0xd3, 0x1f, 0x32, 0x65, 0x04, 0x28, 41 | 0x64, 0xbe, 0x85, 0x9b, 0x2f, 0x59, 0x8a, 0xd7, 0xb0, 0x25, 0xac, 0xaf, 0x12, 0x03, 0xe2, 0xf2, 42 | ]; 43 | 44 | const D: [u32; 16] = [ 45 | 0x44D7, 0x26BC, 0x626B, 0x135E, 0x5789, 0x35E2, 0x7135, 0x09AF, 0x4D78, 0x2F13, 0x6BC4, 0x1AF1, 46 | 0x5E26, 0x3C4D, 0x789A, 0x47AC, 47 | ]; 48 | 49 | #[derive(Debug)] 50 | pub struct ZUC { 51 | s: [u32; 16], 52 | r1: u32, 53 | r2: u32, 54 | x: [u32; 4], 55 | } 56 | 57 | impl ZUC { 58 | pub fn new(k: &[u8], iv: &[u8]) -> ZUC { 59 | let mut s = [0 as u32; 16]; 60 | for i in 0..16 { 61 | s[i] = make_u31(k[i] as u32, D[i], iv[i] as u32); 62 | } 63 | let mut zuc = ZUC { 64 | s, 65 | r1: 0, 66 | r2: 0, 67 | x: [0; 4], 68 | }; 69 | 70 | for _ in 0..32 { 71 | zuc.bit_reconstruction(); 72 | let w = zuc.f(); 73 | zuc.lfsr_with_initialization_mode(w >> 1); 74 | } 75 | zuc.generate_keystream(1); 76 | zuc 77 | } 78 | 79 | fn bit_reconstruction(&mut self) { 80 | self.x[0] = ((self.s[15] & 0x7FFF8000) << 1) | (self.s[14] & 0xFFFF); 81 | self.x[1] = ((self.s[11] & 0xFFFF) << 16) | (self.s[9] >> 15); 82 | self.x[2] = ((self.s[7] & 0xFFFF) << 16) | (self.s[5] >> 15); 83 | self.x[3] = ((self.s[2] & 0xFFFF) << 16) | (self.s[0] >> 15); 84 | } 85 | 86 | fn f(&mut self) -> u32 { 87 | let w = (self.x[0] ^ self.r1).wrapping_add(self.r2); 88 | let w1 = self.r1.wrapping_add(self.x[1]); 89 | let w2 = self.r2 ^ self.x[2]; 90 | 91 | let u = l1((w1 << 16) | (w2 >> 16)); 92 | let v = l2((w2 << 16) | (w1 >> 16)); 93 | 94 | self.r1 = sbox(u); 95 | self.r2 = sbox(v); 96 | w 97 | } 98 | 99 | fn lfsr_with_initialization_mode(&mut self, u: u32) { 100 | let v = self.s[0]; 101 | let v = add31(v, rot31(self.s[0], 8)); 102 | let v = add31(v, rot31(self.s[4], 20)); 103 | let v = add31(v, rot31(self.s[10], 21)); 104 | let v = add31(v, rot31(self.s[13], 17)); 105 | let v = add31(v, rot31(self.s[15], 15)); 106 | 107 | let mut s16 = add31(v, u); 108 | 109 | if s16 == 0 { 110 | s16 = 2147483647; 111 | } 112 | for i in 0..15 { 113 | self.s[i] = self.s[i + 1]; 114 | } 115 | self.s[15] = s16; 116 | } 117 | 118 | fn lfsr_with_work_mode(&mut self) { 119 | let v = self.s[0]; 120 | let v = add31(v, rot31(self.s[0], 8)); 121 | let v = add31(v, rot31(self.s[4], 20)); 122 | let v = add31(v, rot31(self.s[10], 21)); 123 | let v = add31(v, rot31(self.s[13], 17)); 124 | let mut s16 = add31(v, rot31(self.s[15], 15)); 125 | if s16 == 0 { 126 | s16 = 2147483647; 127 | } 128 | for i in 0..15 { 129 | self.s[i] = self.s[i + 1]; 130 | } 131 | self.s[15] = s16; 132 | } 133 | 134 | pub fn generate_keystream(&mut self, n: usize) -> Vec { 135 | let mut keystream = vec![]; 136 | for _ in 0..n { 137 | self.bit_reconstruction(); 138 | let z = self.f() ^ self.x[3]; 139 | self.lfsr_with_work_mode(); 140 | keystream.push(z); 141 | } 142 | keystream 143 | } 144 | } 145 | 146 | #[inline] 147 | fn make_u32(a: u32, b: u32, c: u32, d: u32) -> u32 { 148 | a << 24 | b << 16 | c << 8 | d 149 | } 150 | 151 | #[inline] 152 | fn make_u31(k: u32, d: u32, iv: u32) -> u32 { 153 | k << 23 | d << 8 | iv 154 | } 155 | 156 | #[inline] 157 | fn sbox(x: u32) -> u32 { 158 | make_u32( 159 | S0[(x >> 24) as usize] as u32, 160 | S1[((x >> 16) & 0xFF) as usize] as u32, 161 | S0[((x >> 8) & 0xFF) as usize] as u32, 162 | S1[(x & 0xFF) as usize] as u32, 163 | ) 164 | 165 | // let idx = x.to_be_bytes(); 166 | // let (y0, y1, y2, y3) = ( 167 | // S0[idx[0] as usize], S1[idx[1] as usize], S0[idx[2] as usize], S1[idx[3] as usize] 168 | // ); 169 | // u32::from_be_bytes([y0, y1, y2, y3]) 170 | } 171 | 172 | #[inline] 173 | fn rot31(a: u32, k: u32) -> u32 { 174 | ((a << k) | (a >> (31 - k))) & 0x7FFFFFFF 175 | } 176 | 177 | #[inline] 178 | fn add31(a: u32, b: u32) -> u32 { 179 | let c = a.wrapping_add(b); 180 | (c & 0x7FFFFFFF).wrapping_add(c >> 31) 181 | } 182 | 183 | fn l1(x: u32) -> u32 { 184 | x ^ x.rotate_left(2) ^ x.rotate_left(10) ^ x.rotate_left(18) ^ x.rotate_left(24) 185 | } 186 | 187 | fn l2(x: u32) -> u32 { 188 | x ^ x.rotate_left(8) ^ x.rotate_left(14) ^ x.rotate_left(22) ^ x.rotate_left(30) 189 | } 190 | 191 | #[cfg(test)] 192 | mod zuc_test { 193 | use crate::ZUC; 194 | 195 | #[test] 196 | fn test() { 197 | let key = [0u8; 16]; 198 | let iv = [0u8; 16]; 199 | let mut zuc = ZUC::new(&key, &iv); 200 | let rs = zuc.generate_keystream(2); 201 | for z in rs { 202 | println!("{:x}", z) 203 | } 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /gm-sm9/src/fields/fp2.rs: -------------------------------------------------------------------------------- 1 | use crate::fields::fp::{fp_from_hex, Fp}; 2 | use crate::fields::FieldElement; 3 | 4 | #[derive(Debug, Copy, Clone)] 5 | pub struct Fp2 { 6 | pub(crate) c0: Fp, 7 | pub(crate) c1: Fp, 8 | } 9 | 10 | impl Fp2 { 11 | pub(crate) fn fp_mul_fp(&self, k: &Fp) -> Fp2 { 12 | Fp2 { 13 | c0: self.c0.fp_mul(k), 14 | c1: self.c1.fp_mul(k), 15 | } 16 | } 17 | } 18 | 19 | impl PartialEq for Fp2 { 20 | fn eq(&self, other: &Self) -> bool { 21 | self.c0.eq(&other.c0) && self.c1.eq(&other.c1) 22 | } 23 | } 24 | 25 | impl Eq for Fp2 {} 26 | 27 | impl FieldElement for Fp2 { 28 | fn zero() -> Self { 29 | Fp2 { 30 | c0: Fp::zero(), 31 | c1: Fp::zero(), 32 | } 33 | } 34 | 35 | fn one() -> Self { 36 | Fp2 { 37 | c0: Fp::one(), 38 | c1: Fp::zero(), 39 | } 40 | } 41 | 42 | fn is_zero(&self) -> bool { 43 | self.c0.is_zero() && self.c1.is_zero() 44 | } 45 | 46 | fn fp_sqr(&self) -> Self { 47 | let mut r0 = Fp::zero(); 48 | let mut r1 = Fp::zero(); 49 | let mut t0 = Fp::zero(); 50 | let mut t1 = Fp::zero(); 51 | 52 | r1 = self.c0.fp_mul(&self.c1); 53 | 54 | // r0 = (a0 + a1) * (a0 - 2a1) + a0 * a1 55 | t0 = self.c0.fp_add(&self.c1); 56 | t1 = self.c1.fp_double(); 57 | t1 = self.c0.fp_sub(&t1); 58 | 59 | r0 = t0.fp_mul(&t1); 60 | r0 = r0.fp_add(&r1); 61 | 62 | // r1 = 2 * a0 * a1 63 | r1 = r1.fp_double(); 64 | 65 | Self { c0: r0, c1: r1 } 66 | } 67 | 68 | fn fp_double(&self) -> Self { 69 | Fp2 { 70 | c0: self.c0.fp_double(), 71 | c1: self.c1.fp_double(), 72 | } 73 | } 74 | 75 | fn fp_triple(&self) -> Self { 76 | Fp2 { 77 | c0: self.c0.fp_triple(), 78 | c1: self.c1.fp_triple(), 79 | } 80 | } 81 | 82 | fn fp_add(&self, rhs: &Self) -> Self { 83 | Fp2 { 84 | c0: self.c0.fp_add(&rhs.c0), 85 | c1: self.c1.fp_add(&rhs.c1), 86 | } 87 | } 88 | 89 | fn fp_sub(&self, rhs: &Self) -> Self { 90 | Fp2 { 91 | c0: self.c0.fp_sub(&rhs.c0), 92 | c1: self.c1.fp_sub(&rhs.c1), 93 | } 94 | } 95 | 96 | fn fp_mul(&self, rhs: &Self) -> Self { 97 | let mut r0 = Fp::zero(); 98 | let mut r1 = Fp::zero(); 99 | let mut t = Fp::zero(); 100 | 101 | r0 = self.c0.fp_add(&self.c1); 102 | t = rhs.c0.fp_add(&rhs.c1); 103 | r1 = t.fp_mul(&r0); 104 | 105 | // r0 = a0 * b0 - 2 * a1 * b1 106 | r0 = self.c0.fp_mul(&rhs.c0); 107 | t = self.c1.fp_mul(&rhs.c1); 108 | 109 | // r1 = (a0 + a1) * (b0 + b1) - a0 * b0 - a1 * b1 110 | r1 = r1.fp_sub(&r0); 111 | r1 = r1.fp_sub(&t); 112 | 113 | t = t.fp_double(); 114 | r0 = r0.fp_sub(&t); 115 | 116 | Self { c0: r0, c1: r1 } 117 | } 118 | 119 | fn fp_neg(&self) -> Self { 120 | Fp2 { 121 | c0: self.c0.fp_neg(), 122 | c1: self.c1.fp_neg(), 123 | } 124 | } 125 | 126 | fn fp_div2(&self) -> Self { 127 | Fp2 { 128 | c0: self.c0.fp_div2(), 129 | c1: self.c1.fp_div2(), 130 | } 131 | } 132 | 133 | fn fp_inv(&self) -> Self { 134 | let mut r: Fp2 = Fp2::zero(); 135 | 136 | let mut k = Fp::zero(); 137 | let mut t = Fp::zero(); 138 | 139 | let mut r0 = Fp::zero(); 140 | let mut r1 = Fp::zero(); 141 | 142 | if self.c0.is_zero() { 143 | // r0 = 0 144 | // r1 = -(2 * a1)^-1 145 | r1 = self.c1.fp_double(); 146 | r1 = self.c1.fp_inv(); 147 | r1 = r1.fp_neg(); 148 | } else if self.c1.is_zero() { 149 | // r1 = 0 150 | // r0 = a0^-1 151 | r0 = self.c0.fp_inv(); 152 | } else { 153 | // k = (a[0]^2 + 2 * a[1]^2)^-1 154 | k = self.c0.fp_sqr(); 155 | t = self.c1.fp_sqr(); 156 | t = t.fp_double(); 157 | k = k.fp_add(&t); 158 | k = k.fp_inv(); 159 | 160 | // r[0] = a[0] * k 161 | r0 = self.c0.fp_mul(&k); 162 | 163 | // r[1] = -a[1] * k 164 | r1 = self.c1.fp_mul(&k); 165 | r1 = r1.fp_neg(); 166 | } 167 | r.c0 = r0; 168 | r.c1 = r1; 169 | r 170 | } 171 | 172 | fn to_bytes_be(&self) -> Vec { 173 | let mut bytes: Vec = vec![]; 174 | bytes.extend_from_slice(&self.c1.to_bytes_be().as_slice()); 175 | bytes.extend_from_slice(&self.c0.to_bytes_be().as_slice()); 176 | bytes 177 | } 178 | } 179 | 180 | impl Fp2 { 181 | pub(crate) fn div(&self, rhs: &Self) -> Self { 182 | let t = rhs.fp_inv(); 183 | self.fp_mul(&t) 184 | } 185 | 186 | pub(crate) fn conjugate(&self) -> Self { 187 | let r0 = self.c0; 188 | let r1 = self.c1.fp_neg(); 189 | Self { c0: r0, c1: r1 } 190 | } 191 | 192 | pub(crate) fn a_mul_u(&self) -> Self { 193 | let mut r0 = Fp::zero(); 194 | let mut a0 = Fp::zero(); 195 | let mut a1 = Fp::zero(); 196 | 197 | a0 = self.c0; 198 | a1 = self.c1; 199 | 200 | // r0 = -2 * a1 201 | r0 = a1.fp_double(); 202 | r0 = r0.fp_neg(); 203 | 204 | //r1 = a0 205 | Self { c0: r0, c1: a0 } 206 | } 207 | 208 | pub(crate) fn fp_mul_u(&self, rhs: &Self) -> Self { 209 | let mut t0 = Fp::zero(); 210 | let mut t1 = Fp::zero(); 211 | let mut t2 = Fp::zero(); 212 | 213 | // t2 = (a0 + a1) * (b0 + b1) 214 | t0 = self.c0.fp_add(&self.c1); 215 | t1 = rhs.c0.fp_add(&rhs.c1); 216 | t2 = t0.fp_mul(&t1); 217 | 218 | // t0 = a0 * b0 219 | t0 = self.c0.fp_mul(&rhs.c0); 220 | 221 | // t1 = a1 * b1 222 | t1 = self.c1.fp_mul(&rhs.c1); 223 | 224 | // r0 = -2 *(t2 - t0 - t1) = -2 * (a0 * b1 + a1 * b0) 225 | t2 = t2.fp_sub(&t0); 226 | t2 = t2.fp_sub(&t1); 227 | t2 = t2.fp_double(); 228 | t2 = t2.fp_neg(); 229 | 230 | // r1 = t0 - 2*t1 = a0 * b0 - 2(a1 * b1) 231 | t0 = t0.fp_sub(&t1.fp_double()); 232 | 233 | Self { c0: t2, c1: t0 } 234 | } 235 | 236 | pub(crate) fn sqr_u(&self) -> Self { 237 | let mut r: Fp2 = Fp2::zero(); 238 | let mut r0 = Fp::zero(); 239 | let mut r1 = Fp::zero(); 240 | let mut t = Fp::zero(); 241 | 242 | // r0 = -4 * a0 * a1 243 | r0 = self.c0.fp_mul(&self.c1); 244 | r0 = r0.fp_double(); 245 | r0 = r0.fp_double(); 246 | r0 = r0.fp_neg(); 247 | 248 | // r1 = a0^2 - 2 * a1^2 249 | r1 = self.c0.fp_sqr(); 250 | t = self.c1.fp_sqr(); 251 | t = t.fp_double(); 252 | r1 = r1.fp_sub(&t); 253 | 254 | r.c0 = r0; 255 | r.c1 = r1; 256 | r 257 | } 258 | 259 | pub fn from_hex(hex: [&str; 2]) -> Fp2 { 260 | Fp2 { 261 | c0: fp_from_hex(hex[0]), 262 | c1: fp_from_hex(hex[1]), 263 | } 264 | } 265 | } 266 | 267 | #[cfg(test)] 268 | mod test_mod_operation { 269 | use crate::fields::fp::{fp_from_mont, fp_to_mont}; 270 | use crate::fields::fp2::Fp2; 271 | use crate::fields::FieldElement; 272 | 273 | #[test] 274 | fn test_mod_op() { 275 | let mut a: Fp2 = Fp2 { 276 | c0: [ 277 | 0x6215BBA5C999A7C7, 278 | 0x47EFBA98A71A0811, 279 | 0x5F3170153D278FF2, 280 | 0xA7CF28D519BE3DA6, 281 | ], 282 | c1: [ 283 | 0x856DC76B84EBEB96, 284 | 0x0736A96FA347C8BD, 285 | 0x66BA0D262CBEE6ED, 286 | 0x17509B092E845C12, 287 | ], 288 | }; 289 | 290 | let mut b: Fp2 = Fp2 { 291 | c0: [ 292 | 0x8F14D65696EA5E32, 293 | 0x414D2177386A92DD, 294 | 0x6CE843ED24A3B573, 295 | 0x29DBA116152D1F78, 296 | ], 297 | c1: [ 298 | 0x0AB1B6791B94C408, 299 | 0x1CE0711C5E392CFB, 300 | 0xE48AFF4B41B56501, 301 | 0x9F64080B3084F733, 302 | ], 303 | }; 304 | 305 | a.c0 = fp_to_mont(&a.c0); 306 | a.c1 = fp_to_mont(&a.c1); 307 | 308 | b.c0 = fp_to_mont(&b.c0); 309 | b.c1 = fp_to_mont(&b.c1); 310 | 311 | let mut r = a.fp_add(&b); 312 | r.c0 = fp_from_mont(&r.c0); 313 | r.c1 = fp_from_mont(&r.c1); 314 | r.c0.reverse(); 315 | r.c1.reverse(); 316 | println!("fp_add ={:x?}", r); // [1b6ac9eb2c47b62c, f61608b26c3c7e20, 674a48c4c509ac13, bbaf6d47d32c07c], c1: [74a3145c65ac54, 7541612178e584a9, 2248740e70606dc, aaafe2bcbd2f6a21] 317 | } 318 | } 319 | -------------------------------------------------------------------------------- /gm-sm2/src/util.rs: -------------------------------------------------------------------------------- 1 | use byteorder::{BigEndian, WriteBytesExt}; 2 | use gm_sm3::sm3_hash; 3 | 4 | use crate::error::{Sm2Error, Sm2Result}; 5 | use crate::fields::FieldModOperation; 6 | use crate::fields::fp64::{fp_from_mont, SM2_G_X, SM2_G_Y, SM2_MODP_MONT_A, SM2_MODP_MONT_B}; 7 | use crate::p256_ecc::Point; 8 | 9 | pub(crate) const DEFAULT_ID: &'static str = "1234567812345678"; 10 | 11 | 12 | pub fn compute_za(id: &str, pk: &Point) -> Sm2Result<[u8; 32]> { 13 | if !pk.is_valid() { 14 | return Err(Sm2Error::InvalidPublic); 15 | } 16 | let mut prepend: Vec = Vec::new(); 17 | if id.len() * 8 > 65535 { 18 | return Err(Sm2Error::IdTooLong); 19 | } 20 | prepend 21 | .write_u16::((id.len() * 8) as u16) 22 | .unwrap(); 23 | for c in id.bytes() { 24 | prepend.push(c); 25 | } 26 | 27 | prepend.extend_from_slice(&fp_from_mont(&SM2_MODP_MONT_A).to_byte_be()); 28 | prepend.extend_from_slice(&fp_from_mont(&SM2_MODP_MONT_B).to_byte_be()); 29 | prepend.extend_from_slice(&SM2_G_X.to_byte_be()); 30 | prepend.extend_from_slice(&SM2_G_Y.to_byte_be()); 31 | 32 | let pk_affine = pk.to_affine_point(); 33 | prepend.extend_from_slice(&fp_from_mont(&pk_affine.x).to_byte_be()); 34 | prepend.extend_from_slice(&fp_from_mont(&pk_affine.y).to_byte_be()); 35 | 36 | Ok(sm3_hash(&prepend)) 37 | } 38 | 39 | pub fn xor_bytes(a: &[u8], b: &[u8]) -> Vec { 40 | // 确保两个向量的长度相同 41 | assert_eq!(a.len(), b.len()); 42 | let mut result = Vec::with_capacity(a.len()); 43 | for i in 0..a.len() { 44 | result.push(a[i] ^ b[i]); 45 | } 46 | result 47 | } 48 | 49 | #[inline] 50 | pub fn kdf(z: &[u8], klen: usize) -> Vec { 51 | let mut ct = 0x00000001u32; 52 | let bound = ((klen as f64) / 32.0).ceil() as u32; 53 | let mut h_a = Vec::new(); 54 | for _i in 1..bound { 55 | let mut prepend = Vec::new(); 56 | prepend.extend_from_slice(z); 57 | prepend.extend_from_slice(&ct.to_be_bytes()); 58 | 59 | let h_a_i = sm3_hash(&prepend[..]); 60 | h_a.extend_from_slice(&h_a_i); 61 | ct += 1; 62 | } 63 | 64 | let mut prepend = Vec::new(); 65 | prepend.extend_from_slice(z); 66 | prepend.extend_from_slice(&ct.to_be_bytes()); 67 | 68 | let last = sm3_hash(&prepend[..]); 69 | if klen % 32 == 0 { 70 | h_a.extend_from_slice(&last); 71 | } else { 72 | h_a.extend_from_slice(&last[0..(klen % 32)]); 73 | } 74 | h_a 75 | } 76 | 77 | #[inline(always)] 78 | pub const fn add_raw(a: &[u32; 8], b: &[u32; 8]) -> ([u32; 8], bool) { 79 | let mut sum = [0; 8]; 80 | let mut carry = false; 81 | let mut i = 7; 82 | loop { 83 | let (t_sum, c) = { 84 | let (m, c1) = a[i].overflowing_add(b[i]); 85 | let (r, c2) = m.overflowing_add(carry as u32); 86 | (r & 0xffff_ffff, c1 || c2) 87 | }; 88 | sum[i] = t_sum; 89 | carry = c; 90 | if i == 0 { 91 | break; 92 | } 93 | i -= 1; 94 | } 95 | (sum, carry) 96 | } 97 | 98 | #[inline(always)] 99 | pub const fn add_raw_u64(a: &[u64; 4], b: &[u64; 4]) -> ([u64; 4], bool) { 100 | let mut sum = [0; 4]; 101 | let mut carry = false; 102 | let mut i = 3; 103 | loop { 104 | let (t_sum, c) = { 105 | let (m, c1) = a[i].overflowing_add(b[i]); 106 | let (r, c2) = m.overflowing_add(carry as u64); 107 | (r & 0xffff_ffff_ffff_ffff, c1 || c2) 108 | }; 109 | sum[i] = t_sum; 110 | carry = c; 111 | if i == 0 { 112 | break; 113 | } 114 | i -= 1; 115 | } 116 | (sum, carry) 117 | } 118 | 119 | #[inline(always)] 120 | pub const fn sub_raw_u64(a: &[u64; 4], b: &[u64; 4]) -> ([u64; 4], bool) { 121 | let mut r = [0; 4]; 122 | let mut borrow = false; 123 | let mut j = 0; 124 | loop { 125 | let i = 3 - j; 126 | let (diff, bor) = { 127 | let (a, b1) = a[i].overflowing_sub(borrow as u64); 128 | let (res, b2) = a.overflowing_sub(b[i]); 129 | (res, b1 || b2) 130 | }; 131 | r[i] = diff; 132 | borrow = bor; 133 | if j == 3 { 134 | break; 135 | } 136 | j += 1; 137 | } 138 | (r, borrow) 139 | } 140 | 141 | #[inline(always)] 142 | pub const fn sub_raw(a: &[u32; 8], b: &[u32; 8]) -> ([u32; 8], bool) { 143 | let mut r = [0; 8]; 144 | let mut borrow = false; 145 | let mut j = 0; 146 | loop { 147 | let i = 7 - j; 148 | let (diff, bor) = { 149 | let (a, b1) = a[i].overflowing_sub(borrow as u32); 150 | let (res, b2) = a.overflowing_sub(b[i]); 151 | (res, b1 || b2) 152 | }; 153 | r[i] = diff; 154 | borrow = bor; 155 | if j == 7 { 156 | break; 157 | } 158 | j += 1; 159 | } 160 | (r, borrow) 161 | } 162 | 163 | #[inline(always)] 164 | pub const fn mul_raw(a: &[u32; 8], b: &[u32; 8]) -> [u32; 16] { 165 | let mut local: u64 = 0; 166 | let mut carry: u64 = 0; 167 | let mut ret: [u32; 16] = [0; 16]; 168 | let mut ret_idx = 0; 169 | while ret_idx < 15 { 170 | let index = 15 - ret_idx; 171 | let mut a_idx = 0; 172 | while a_idx < 8 { 173 | if a_idx > ret_idx { 174 | break; 175 | } 176 | let b_idx = ret_idx - a_idx; 177 | if b_idx < 8 { 178 | let (hi, lo) = { 179 | let uv = (a[7 - a_idx] as u64) * (b[7 - b_idx] as u64); 180 | let u = uv >> 32; 181 | let v = uv & 0xffff_ffff; 182 | (u, v) 183 | }; 184 | local += lo; 185 | carry += hi; 186 | } 187 | a_idx += 1; 188 | } 189 | carry += local >> 32; 190 | local &= 0xffff_ffff; 191 | ret[index] = local as u32; 192 | local = carry; 193 | carry = 0; 194 | ret_idx += 1; 195 | } 196 | ret[0] = local as u32; 197 | ret 198 | } 199 | 200 | #[inline(always)] 201 | pub const fn mul_raw_u64(a: &[u64; 4], b: &[u64; 4]) -> [u64; 8] { 202 | let mut local: u128 = 0; 203 | let mut carry: u128 = 0; 204 | let mut ret: [u64; 8] = [0; 8]; 205 | let mut ret_idx = 0; 206 | while ret_idx < 7 { 207 | let index = 7 - ret_idx; 208 | let mut a_idx = 0; 209 | while a_idx < 4 { 210 | if a_idx > ret_idx { 211 | break; 212 | } 213 | let b_idx = ret_idx - a_idx; 214 | if b_idx < 4 { 215 | let (hi, lo) = { 216 | let uv = (a[3 - a_idx] as u128) * (b[3 - b_idx] as u128); 217 | let u = uv >> 64; 218 | let v = uv & 0xffff_ffff_ffff_ffff; 219 | (u, v) 220 | }; 221 | local += lo; 222 | carry += hi; 223 | } 224 | a_idx += 1; 225 | } 226 | carry += local >> 64; 227 | local &= 0xffff_ffff_ffff_ffff; 228 | ret[index] = local as u64; 229 | local = carry; 230 | carry = 0; 231 | ret_idx += 1; 232 | } 233 | ret[0] = local as u64; 234 | ret 235 | } 236 | 237 | #[cfg(test)] 238 | mod test_operation { 239 | use num_bigint::BigUint; 240 | use num_traits::Num; 241 | 242 | use crate::util::{add_raw_u64, mul_raw_u64, sub_raw_u64}; 243 | 244 | #[test] 245 | fn test_raw_add_u64() { 246 | let a: [u64; 4] = [ 247 | 0xF9B7213BAF82D65B, 248 | 0xEE265948D19C17AB, 249 | 0xD2AAB97FD34EC120, 250 | 0x3722755292130B08, 251 | ]; 252 | 253 | let b: [u64; 4] = [ 254 | 0x54806C11D8806141, 255 | 0xF1DD2C190F5E93C4, 256 | 0x597B6027B441A01F, 257 | 0x85AEF3D078640C98, 258 | ]; 259 | 260 | let a1 = BigUint::from_str_radix( 261 | "F9B7213BAF82D65BEE265948D19C17ABD2AAB97FD34EC1203722755292130B08", 262 | 16, 263 | ) 264 | .unwrap(); 265 | let b1 = BigUint::from_str_radix( 266 | "54806C11D8806141F1DD2C190F5E93C4597B6027B441A01F85AEF3D078640C98", 267 | 16, 268 | ) 269 | .unwrap(); 270 | 271 | let (r, _c) = add_raw_u64(&a, &b); 272 | println!("sum r={:?}", r); 273 | 274 | let mut sum = (&a1 + &b1).to_u64_digits(); 275 | sum.reverse(); 276 | println!("sum r={:?}", &sum[1..]); 277 | 278 | let (r, _c) = sub_raw_u64(&a, &b); 279 | println!("sub r={:?}", r); 280 | 281 | let mut sub = (&a1 - &b1).to_u64_digits(); 282 | sub.reverse(); 283 | println!("sub r={:?}", sub.as_slice()); 284 | 285 | let r = mul_raw_u64(&a, &b); 286 | println!("mul r={:?}", r); 287 | 288 | let mut mul = (&a1 * &b1).to_u64_digits(); 289 | mul.reverse(); 290 | println!("mul r={:?}", mul.as_slice()); 291 | } 292 | } 293 | -------------------------------------------------------------------------------- /gm-sm9/src/u256.rs: -------------------------------------------------------------------------------- 1 | use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; 2 | use rand::RngCore; 3 | use std::io::Cursor; 4 | 5 | pub type U256 = [u64; 4]; 6 | pub type U512 = [u64; 8]; 7 | 8 | pub(crate) const SM9_ZERO: U256 = [0, 0, 0, 0]; 9 | pub(crate) const SM9_ONE: U256 = [1, 0, 0, 0]; 10 | 11 | #[inline(always)] 12 | pub fn sm9_random_u256(range: &U256) -> U256 { 13 | let mut rng = rand::thread_rng(); 14 | let mut ret; 15 | loop { 16 | let mut buf: [u8; 32] = [0; 32]; 17 | rng.fill_bytes(&mut buf[..]); 18 | ret = u256_from_be_bytes(&buf); 19 | if u256_cmp(&ret, range) < 0 && ret >= [1, 0, 0, 0] { 20 | break; 21 | } 22 | } 23 | ret 24 | } 25 | 26 | #[inline(always)] 27 | pub const fn u256_add(a: &U256, b: &U256) -> (U256, bool) { 28 | let mut sum = [0; 4]; 29 | let mut carry = false; 30 | let mut i = 0; 31 | loop { 32 | let (t_sum, c) = { 33 | let (m, c1) = a[i].overflowing_add(b[i]); 34 | let (r, c2) = m.overflowing_add(carry as u64); 35 | (r, c1 || c2) 36 | }; 37 | sum[i] = t_sum; 38 | carry = c; 39 | if i == 3 { 40 | break; 41 | } 42 | i += 1; 43 | } 44 | (sum, carry) 45 | } 46 | 47 | #[inline(always)] 48 | pub const fn u512_add(a: &U512, b: &U512) -> (U512, bool) { 49 | let mut sum = [0; 8]; 50 | let mut carry = false; 51 | let mut i = 0; 52 | loop { 53 | let (t_sum, c) = { 54 | let (m, c1) = a[i].overflowing_add(b[i]); 55 | let (r, c2) = m.overflowing_add(carry as u64); 56 | (r, c1 || c2) 57 | }; 58 | sum[i] = t_sum; 59 | carry = c; 60 | if i == 7 { 61 | break; 62 | } 63 | i += 1; 64 | } 65 | (sum, carry) 66 | } 67 | 68 | #[inline(always)] 69 | pub const fn u256_sub(a: &U256, b: &U256) -> (U256, bool) { 70 | let mut r = [0; 4]; 71 | let mut borrow = false; 72 | let mut j = 3; 73 | loop { 74 | let i = 3 - j; 75 | let (diff, bor) = { 76 | let (a, b1) = a[i].overflowing_sub(borrow as u64); 77 | let (res, b2) = a.overflowing_sub(b[i]); 78 | (res, b1 || b2) 79 | }; 80 | r[i] = diff; 81 | borrow = bor; 82 | if j == 0 { 83 | break; 84 | } 85 | j -= 1; 86 | } 87 | (r, borrow) 88 | } 89 | 90 | #[inline(always)] 91 | pub const fn u512_sub(a: &U512, b: &U512) -> (U512, bool) { 92 | let mut r = [0; 8]; 93 | let mut borrow = false; 94 | let mut j = 7; 95 | loop { 96 | let i = 7 - j; 97 | let (diff, bor) = { 98 | let (a, b1) = a[i].overflowing_sub(borrow as u64); 99 | let (res, b2) = a.overflowing_sub(b[i]); 100 | (res, b1 || b2) 101 | }; 102 | r[i] = diff; 103 | borrow = bor; 104 | if j == 0 { 105 | break; 106 | } 107 | j -= 1; 108 | } 109 | (r, borrow) 110 | } 111 | 112 | #[inline(always)] 113 | pub const fn u256_cmp(a: &U256, b: &U256) -> i32 { 114 | if a[3] > b[3] { 115 | return 1; 116 | } 117 | if a[3] < b[3] { 118 | return -1; 119 | } 120 | if a[2] > b[2] { 121 | return 1; 122 | } 123 | if a[2] < b[2] { 124 | return -1; 125 | } 126 | if a[1] > b[1] { 127 | return 1; 128 | } 129 | if a[1] < b[1] { 130 | return -1; 131 | } 132 | if a[0] > b[0] { 133 | return 1; 134 | } 135 | if a[0] < b[0] { 136 | return -1; 137 | } 138 | 0 139 | } 140 | 141 | #[inline(always)] 142 | pub fn u256_mul(a: &U256, b: &U256) -> U512 { 143 | let mut a_: [u64; 8] = [0; 8]; 144 | let mut b_: [u64; 8] = [0; 8]; 145 | let mut ret: [u64; 8] = [0; 8]; 146 | let mut s: [u64; 16] = [0; 16]; 147 | 148 | for i in 0..4 { 149 | a_[2 * i] = a[i] & 0xffffffff; 150 | b_[2 * i] = b[i] & 0xffffffff; 151 | a_[2 * i + 1] = a[i] >> 32; 152 | b_[2 * i + 1] = b[i] >> 32; 153 | } 154 | 155 | let mut u = 0; 156 | for i in 0..8 { 157 | u = 0; 158 | for j in 0..8 { 159 | u = s[i + j] + a_[i] * b_[j] + u; 160 | s[i + j] = u & 0xffffffff; 161 | u >>= 32; 162 | } 163 | s[i + 8] = u; 164 | } 165 | 166 | for i in 0..8 { 167 | ret[i] = (s[2 * i + 1] << 32) | s[2 * i]; 168 | } 169 | ret 170 | } 171 | 172 | #[inline(always)] 173 | pub fn xor(k: &[u8], data: &[u8], len: usize) -> Vec { 174 | let mut ret: Vec = vec![]; 175 | for i in 0..len { 176 | ret.push(k[i] ^ data[i]); 177 | } 178 | ret 179 | } 180 | 181 | #[inline(always)] 182 | pub fn u256_to_be_bytes(a: &U256) -> Vec { 183 | let mut ret: Vec = Vec::new(); 184 | for i in (0..4).rev() { 185 | ret.write_u64::(a[i]).unwrap(); 186 | } 187 | ret 188 | } 189 | 190 | #[inline(always)] 191 | pub fn u256_to_bits(a: U256) -> [char; 256] { 192 | let mut bits = ['0'; 256]; // 初始化长度为 256 的字符数组,默认值为 '0' 193 | let mut index = 0; 194 | for i in (0..4).rev() { 195 | // 遍历 4 个 u64 元素,倒序访问 196 | let mut w = a[i]; 197 | for _ in 0..64 { 198 | bits[index] = if (w & 0x8000_0000_0000_0000) != 0 { 199 | '1' 200 | } else { 201 | '0' 202 | }; 203 | w <<= 1; 204 | index += 1; 205 | } 206 | } 207 | bits 208 | } 209 | 210 | #[inline(always)] 211 | pub fn u256_from_hex(hex: &str) -> U256 { 212 | u256_from_be_bytes(&hex::decode(hex).unwrap()) 213 | } 214 | 215 | #[inline(always)] 216 | pub fn u256_from_be_bytes(input: &[u8]) -> U256 { 217 | let mut elem = [0, 0, 0, 0]; 218 | let mut c = Cursor::new(input); 219 | for i in (0..4).rev() { 220 | elem[i] = c.read_u64::().unwrap(); 221 | } 222 | elem 223 | } 224 | 225 | pub fn sm9_u256_get_booth(a: &[u64], window_size: u64, i: u64) -> i32 { 226 | let mask = (1 << window_size) - 1; 227 | let (mut n, mut j) = (0_usize, 0_usize); 228 | if i == 0 { 229 | return (((a[0] << 1) & mask) as i32) - ((a[0] & mask) as i32); 230 | } 231 | 232 | j = (i * window_size - 1) as usize; 233 | n = j / 64; 234 | j = j % 64; 235 | 236 | let mut wbits = a[n] >> j; 237 | if (64 - j) < (window_size + 1) as usize && n < 3 { 238 | wbits |= a[n + 1] << (64 - j); 239 | } 240 | ((wbits & mask) as i32) - (((wbits >> 1) & mask) as i32) 241 | } 242 | 243 | #[cfg(test)] 244 | mod test_operation { 245 | use num_bigint::BigUint; 246 | 247 | use crate::u256::{ 248 | sm9_u256_get_booth, u256_add, u256_from_be_bytes, u256_mul, u256_sub, u256_to_be_bytes, 249 | }; 250 | 251 | #[test] 252 | fn test_raw_add_u64() { 253 | let a: [u64; 4] = [ 254 | 0x54806C11D8806141, 255 | 0xF1DD2C190F5E93C4, 256 | 0x597B6027B441A01F, 257 | 0x85AEF3D078640C98, 258 | ]; 259 | 260 | let b: [u64; 4] = [ 261 | 0x0E75C05FB4E3216D, 262 | 0x1006E85F5CDFF073, 263 | 0x1A7CE027B7A46F74, 264 | 0x41E00A53DDA532DA, 265 | ]; 266 | 267 | let a1 = BigUint::from_bytes_be( 268 | &hex::decode("85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141") 269 | .unwrap(), 270 | ); 271 | 272 | let b1 = BigUint::from_bytes_be( 273 | &hex::decode("41E00A53DDA532DA1A7CE027B7A46F741006E85F5CDFF0730E75C05FB4E3216D") 274 | .unwrap(), 275 | ); 276 | 277 | let (mut r, c) = u256_add(&a, &b); 278 | r.reverse(); 279 | let mut sum = (&a1 + &b1).to_u64_digits(); 280 | sum.reverse(); 281 | assert_eq!(r, *sum); 282 | 283 | let (mut r, c) = u256_sub(&a, &b); 284 | r.reverse(); 285 | let mut sub = (&a1 - &b1).to_u64_digits(); 286 | sub.reverse(); 287 | assert_eq!(r, *sub); 288 | 289 | let mut r = u256_mul(&a, &b); 290 | r.reverse(); 291 | let mut mul = (&a1 * &b1).to_u64_digits(); 292 | mul.reverse(); 293 | assert_eq!(r, *mul); 294 | } 295 | 296 | #[test] 297 | fn test_to_bytes_be() { 298 | let a: [u64; 4] = [ 299 | 0x54806C11D8806141, 300 | 0xF1DD2C190F5E93C4, 301 | 0x597B6027B441A01F, 302 | 0x85AEF3D078640C98, 303 | ]; 304 | 305 | let r_b = [ 306 | 133, 174, 243, 208, 120, 100, 12, 152, 89, 123, 96, 39, 180, 65, 160, 31, 241, 221, 44, 307 | 25, 15, 94, 147, 196, 84, 128, 108, 17, 216, 128, 97, 65, 308 | ]; 309 | 310 | let ret = u256_to_be_bytes(&a); 311 | assert_eq!(ret, r_b); 312 | 313 | let ret = u256_from_be_bytes(&r_b); 314 | assert_eq!(ret, a); 315 | } 316 | 317 | #[test] 318 | fn test_get_booth() { 319 | let k = u256_from_be_bytes( 320 | &hex::decode("123456789abcdef00fedcba987654321123456789abcdef00fedcba987654321") 321 | .unwrap(), 322 | ); 323 | let window_size = 7u64; 324 | let n = (256 + window_size - 1) / window_size; 325 | for i in (0..n).rev() { 326 | let booth = sm9_u256_get_booth(&k, window_size, i); 327 | println!("i = {}, booth = {}", i, booth); 328 | } 329 | } 330 | } 331 | -------------------------------------------------------------------------------- /gm-sm2/src/exchange.rs: -------------------------------------------------------------------------------- 1 | use byteorder::{BigEndian, WriteBytesExt}; 2 | 3 | use gm_sm3::sm3_hash; 4 | 5 | use crate::error::{Sm2Error, Sm2Result}; 6 | use crate::fields::FieldModOperation; 7 | use crate::fields::fn64::{fn_add, fn_mul}; 8 | use crate::fields::fp64::{fp_from_mont, random_u256}; 9 | use crate::key::{gen_keypair, Sm2PrivateKey, Sm2PublicKey}; 10 | use crate::p256_ecc::{g_mul, Point}; 11 | use crate::u256::{SM2_ONE, U256, u256_add, u256_bits_and, u256_sub}; 12 | use crate::util::{compute_za, DEFAULT_ID, kdf}; 13 | 14 | #[derive(Debug)] 15 | pub struct Exchange { 16 | klen: usize, 17 | za: [u8; 32], 18 | sk: Sm2PrivateKey, 19 | v: Option, 20 | r: Option, 21 | r_point: Option, 22 | pub(crate) k: Option>, 23 | 24 | rhs_za: [u8; 32], 25 | rhs_pk: Sm2PublicKey, 26 | } 27 | 28 | /// Build the exchange Pair 29 | /// 30 | pub fn build_ex_pair( 31 | klen: usize, 32 | first_id: &str, 33 | other_id: &str, 34 | ) -> Sm2Result<(Exchange, Exchange)> { 35 | let (pk_a, sk_a) = gen_keypair().unwrap(); 36 | let (pk_b, sk_b) = gen_keypair().unwrap(); 37 | let user_a = Exchange::new(klen, Some(first_id), &pk_a, &sk_a, Some(other_id), &pk_b).unwrap(); 38 | let user_b = Exchange::new(klen, Some(other_id), &pk_b, &sk_b, Some(first_id), &pk_a).unwrap(); 39 | Ok((user_a, user_b)) 40 | } 41 | 42 | impl Exchange { 43 | pub fn new( 44 | klen: usize, 45 | id: Option<&str>, 46 | pk: &Sm2PublicKey, 47 | sk: &Sm2PrivateKey, 48 | rhs_id: Option<&str>, 49 | rhs_pk: &Sm2PublicKey, 50 | ) -> Sm2Result { 51 | let id = id.unwrap_or_else(|| DEFAULT_ID); 52 | let rhs_id = rhs_id.unwrap_or_else(|| DEFAULT_ID); 53 | Ok(Exchange { 54 | klen, 55 | za: compute_za(id, &pk.point)?, 56 | sk: sk.clone(), 57 | v: None, 58 | r: None, 59 | r_point: None, 60 | k: None, 61 | rhs_za: compute_za(rhs_id, &rhs_pk.point)?, 62 | rhs_pk: rhs_pk.clone(), 63 | }) 64 | } 65 | 66 | // Step1: UserA Call 67 | // A1:用随机数发生器产生随机数rA ∈ [1, n-1]; 68 | // A2:计算椭圆曲线点RA = [rA]G=(x1,y1); 69 | // A3:将RA发送给用户B; 70 | pub fn exchange_1(&mut self) -> Sm2Result { 71 | let r = random_u256(); 72 | let r_point = g_mul(&r); 73 | self.r = Some(r); 74 | self.r_point = Some(r_point); 75 | Ok(r_point) 76 | } 77 | 78 | // Step2: UserB Call 79 | // 80 | pub fn exchange_2(&mut self, ra_point: &Point) -> Sm2Result<(Point, [u8; 32])> { 81 | if !ra_point.is_valid() { 82 | return Err(Sm2Error::CheckPointErr); 83 | } 84 | // 2^127 85 | let pow: [u64; 4] = [ 86 | 0x8000000000000000, 87 | 0x0000000000000000, 88 | 0x0000000000000000, 89 | 0x0000000000000000, 90 | ]; 91 | 92 | let r2 = random_u256(); 93 | let r2_point = g_mul(&r2); 94 | self.r = Some(r2); 95 | self.r_point = Some(r2_point); 96 | let r2_point_affine = r2_point.to_affine_point(); 97 | let x2 = fp_from_mont(&r2_point_affine.x); 98 | let y2 = fp_from_mont(&r2_point_affine.y); 99 | let x2_b = u256_add(&pow, &u256_bits_and(&x2, &u256_sub(&pow, &SM2_ONE).0)).0; 100 | let t2 = fn_add( 101 | &self.sk.d, 102 | &fn_mul( 103 | &self.r.as_ref().unwrap(), 104 | &x2_b, 105 | ), 106 | ); 107 | 108 | let ra_point_affine = ra_point.to_affine_point(); 109 | let x1 = fp_from_mont(&ra_point_affine.x); 110 | let y1 = fp_from_mont(&ra_point_affine.y); 111 | let x1_a = u256_add(&pow, &u256_bits_and(&x1, &u256_sub(&pow, &SM2_ONE).0)).0; 112 | 113 | let p = self 114 | .rhs_pk 115 | .value() 116 | .point_add(&ra_point.scalar_mul(&x1_a)); 117 | let v_point = p.scalar_mul(&t2); 118 | if v_point.is_zero() { 119 | return Err(Sm2Error::ZeroPoint); 120 | } 121 | self.v = Some(v_point); 122 | 123 | let v_affine_p = v_point.to_affine_point(); 124 | let xv_bytes = fp_from_mont(&v_affine_p.x).to_byte_be(); 125 | let yv_bytes = fp_from_mont(&v_affine_p.y).to_byte_be(); 126 | 127 | let mut prepend = Vec::new(); 128 | prepend.extend_from_slice(&xv_bytes); 129 | prepend.extend_from_slice(&yv_bytes); 130 | prepend.extend_from_slice(&self.rhs_za); // User A 131 | prepend.extend_from_slice(&self.za); // User B 132 | 133 | let k_b = kdf(&prepend, self.klen); 134 | self.k = Some(k_b); 135 | 136 | let mut temp: Vec = Vec::new(); 137 | temp.extend_from_slice(&xv_bytes); 138 | temp.extend_from_slice(&self.rhs_za); 139 | temp.extend_from_slice(&self.za); 140 | temp.extend_from_slice(&x1.to_byte_be()); 141 | temp.extend_from_slice(&y1.to_byte_be()); 142 | temp.extend_from_slice(&x2.to_byte_be()); 143 | temp.extend_from_slice(&y2.to_byte_be()); 144 | 145 | let mut prepend: Vec = Vec::new(); 146 | prepend.write_u16::(0x02_u16).unwrap(); 147 | prepend.extend_from_slice(&yv_bytes); 148 | prepend.extend_from_slice(&sm3_hash(&temp)); 149 | Ok((r2_point, sm3_hash(&prepend))) 150 | } 151 | 152 | // Step4: UserA Call 153 | // 154 | pub fn exchange_3(&mut self, rb_point: &Point, sb: [u8; 32]) -> Sm2Result<[u8; 32]> { 155 | if !rb_point.is_valid() { 156 | return Err(Sm2Error::CheckPointErr); 157 | } 158 | // 2^127 159 | let pow: [u64; 4] = [ 160 | 0x8000000000000000, 161 | 0x0000000000000000, 162 | 0x0000000000000000, 163 | 0x0000000000000000, 164 | ]; 165 | 166 | let ra_point_affine = self.r_point.unwrap().to_affine_point(); 167 | let x1 = fp_from_mont(&ra_point_affine.x); 168 | let y1 = fp_from_mont(&ra_point_affine.y); 169 | let x1_a = u256_add(&pow, &u256_bits_and(&x1, &u256_sub(&pow, &SM2_ONE).0)).0; 170 | let t_a = fn_add( 171 | &self.sk.d, 172 | &fn_mul( 173 | &self.r.as_ref().unwrap(), 174 | &x1_a, 175 | ), 176 | ); 177 | 178 | let rb_point_affine = rb_point.to_affine_point(); 179 | let x2 = fp_from_mont(&rb_point_affine.x); 180 | let y2 = fp_from_mont(&rb_point_affine.y); 181 | let x2_b = u256_add(&pow, &u256_bits_and(&x2, &u256_sub(&pow, &SM2_ONE).0)).0; 182 | let p = self 183 | .rhs_pk 184 | .value() 185 | .point_add(&rb_point.scalar_mul(&x2_b)); 186 | let u_point = p.scalar_mul(&t_a); 187 | if u_point.is_zero() { 188 | return Err(Sm2Error::ZeroPoint); 189 | } 190 | 191 | let u_affine_p = u_point.to_affine_point(); 192 | let xu_bytes = fp_from_mont(&u_affine_p.x).to_byte_be(); 193 | let yu_bytes = fp_from_mont(&u_affine_p.y).to_byte_be(); 194 | 195 | let mut prepend = Vec::new(); 196 | prepend.extend_from_slice(&xu_bytes); 197 | prepend.extend_from_slice(&yu_bytes); 198 | prepend.extend_from_slice(&self.za); 199 | prepend.extend_from_slice(&self.rhs_za); 200 | 201 | let k_a = kdf(&prepend, self.klen); 202 | self.k = Some(k_a); 203 | 204 | let mut temp: Vec = Vec::new(); 205 | temp.extend_from_slice(&xu_bytes); 206 | temp.extend_from_slice(&self.za); 207 | temp.extend_from_slice(&self.rhs_za); 208 | temp.extend_from_slice(&x1.to_byte_be()); 209 | temp.extend_from_slice(&y1.to_byte_be()); 210 | temp.extend_from_slice(&x2.to_byte_be()); 211 | temp.extend_from_slice(&y2.to_byte_be()); 212 | let temp_hash = sm3_hash(&temp); 213 | 214 | let mut prepend: Vec = Vec::new(); 215 | prepend.write_u16::(0x02_u16).unwrap(); 216 | prepend.extend_from_slice(&yu_bytes); 217 | prepend.extend_from_slice(&temp_hash); 218 | 219 | let s1 = sm3_hash(&prepend); 220 | if s1 != sb { 221 | return Err(Sm2Error::HashNotEqual); 222 | } 223 | 224 | let mut prepend: Vec = Vec::new(); 225 | prepend.write_u16::(0x03_u16).unwrap(); 226 | prepend.extend_from_slice(&yu_bytes); 227 | prepend.extend_from_slice(&temp_hash); 228 | Ok(sm3_hash(&prepend)) 229 | } 230 | 231 | // Step4: UserA Call 232 | pub fn exchange_4(&self, sa: [u8; 32], ra_point: &Point) -> Sm2Result { 233 | let ra_point_affine = ra_point.to_affine_point(); 234 | let x1 = fp_from_mont(&ra_point_affine.x); 235 | let y1 = fp_from_mont(&ra_point_affine.y); 236 | 237 | let r2_point_affine = self.r_point.unwrap().to_affine_point(); 238 | let x2 = fp_from_mont(&r2_point_affine.x); 239 | let y2 = fp_from_mont(&r2_point_affine.y); 240 | 241 | let v_point_affine = self.v.unwrap().to_affine_point(); 242 | let xv = fp_from_mont(&v_point_affine.x); 243 | let yv = fp_from_mont(&v_point_affine.y); 244 | 245 | let mut temp: Vec = Vec::new(); 246 | temp.extend_from_slice(&xv.to_byte_be()); 247 | temp.extend_from_slice(&self.rhs_za); 248 | temp.extend_from_slice(&self.za); 249 | temp.extend_from_slice(&x1.to_byte_be()); 250 | temp.extend_from_slice(&y1.to_byte_be()); 251 | temp.extend_from_slice(&x2.to_byte_be()); 252 | temp.extend_from_slice(&y2.to_byte_be()); 253 | 254 | let mut prepend: Vec = Vec::new(); 255 | prepend.write_u16::(0x03_u16).unwrap(); 256 | prepend.extend_from_slice(&yv.to_byte_be()); 257 | prepend.extend_from_slice(&sm3_hash(&temp)); 258 | let s_2 = sm3_hash(&prepend); 259 | Ok(s_2 == sa) 260 | } 261 | } 262 | -------------------------------------------------------------------------------- /gm-sm9/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("../README.md")] 2 | use crate::fields::fp2::Fp2; 3 | use crate::points::{Point, TwistPoint}; 4 | use crate::u256::U256; 5 | 6 | pub mod error; 7 | pub mod fields; 8 | pub mod key; 9 | pub mod points; 10 | mod sm9_p256_table; 11 | pub mod u256; 12 | 13 | /// Example: 14 | /// 15 | /// ### encrypt & decrypt 16 | /// ```rust 17 | /// use gm_sm9::key::Sm9EncMasterKey; 18 | /// use gm_sm9::points::{Point, TwistPoint}; 19 | /// use gm_sm9::u256::u256_from_be_bytes; 20 | /// 21 | /// fn main() { 22 | /// let data: [u8; 21] = [ 23 | /// 0x43, 0x68, 0x69, 0x6E, 0x65, 0x73, 0x65, 0x20, 0x49, 0x42, 0x53, 0x20, 0x73, 0x74, 24 | /// 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x64, 25 | /// ]; 26 | /// println!("Message = {:?}", &data); 27 | /// let id = [0x42, 0x6F, 0x62u8]; 28 | /// let ke = u256_from_be_bytes( 29 | /// &hex::decode("0001EDEE3778F441F8DEA3D9FA0ACC4E07EE36C93F9A08618AF4AD85CEDE1C22") 30 | /// .unwrap(), 31 | /// ); 32 | /// 33 | /// let msk = Sm9EncMasterKey { 34 | /// ke, 35 | /// ppube: Point::g_mul(&ke), 36 | /// }; 37 | /// 38 | /// let r = msk.extract_key(&id); 39 | /// let r_de = TwistPoint::from_hex( 40 | /// [ 41 | /// "115BAE85F5D8BC6C3DBD9E5342979ACCCF3C2F4F28420B1CB4F8C0B59A19B158", 42 | /// "94736ACD2C8C8796CC4785E938301A139A059D3537B6414140B2D31EECF41683", 43 | /// ], 44 | /// [ 45 | /// "27538A62E7F7BFB51DCE08704796D94C9D56734F119EA44732B50E31CDEB75C1", 46 | /// "7AA5E47570DA7600CD760A0CF7BEAF71C447F3844753FE74FA7BA92CA7D3B55F", 47 | /// ], 48 | /// ); 49 | /// assert_eq!(true, r.unwrap().de.point_equals(&r_de)); 50 | /// 51 | /// let ret = msk.encrypt(&id, &data); 52 | /// println!("Ciphertext = {:?}", ret); 53 | /// 54 | /// let m = r.unwrap().decrypt(&id, &ret).expect("Decryption failed"); 55 | /// println!("Plaintext = {:?}", &m); 56 | /// assert_eq!(true, data == m.as_slice()); 57 | /// } 58 | /// 59 | /// ``` 60 | /// 61 | /// 62 | /// ### sign & verify 63 | /// ```rust 64 | /// use gm_sm9::key::{Sm9SignMasterKey, Sm9SignKey}; 65 | /// use gm_sm9::points::{Point, TwistPoint}; 66 | /// use gm_sm9::u256::u256_from_be_bytes; 67 | /// fn main() { 68 | /// let data: [u8; 20] = [ 69 | /// 0x43, 0x68, 0x69, 0x6E, 0x65, 0x73, 0x65, 0x20, 0x49, 0x42, 0x53, 0x20, 0x73, 0x74, 70 | /// 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 71 | /// ]; 72 | /// 73 | /// let ida = [0x41, 0x6C, 0x69, 0x63, 0x65u8]; 74 | /// 75 | /// let ks = u256_from_be_bytes( 76 | /// &hex::decode("000130E78459D78545CB54C587E02CF480CE0B66340F319F348A1D5B1F2DC5F4") 77 | /// .unwrap(), 78 | /// ); 79 | /// let msk = Sm9SignMasterKey { 80 | /// ks, 81 | /// ppubs: TwistPoint::g_mul(&ks), 82 | /// }; 83 | /// 84 | /// let r_ds = Point::from_hex([ 85 | /// "A5702F05CF1315305E2D6EB64B0DEB923DB1A0BCF0CAFF90523AC8754AA69820", 86 | /// "78559A844411F9825C109F5EE3F52D720DD01785392A727BB1556952B2B013D3", 87 | /// ]); 88 | /// let r = msk.extract_key(&ida); 89 | /// let ps = r.unwrap(); 90 | /// assert_eq!(true, ps.ds.point_equals(&r_ds)); 91 | /// 92 | /// println!("Message = {:?}", &data); 93 | /// let (h, s) = ps.sign(&data).unwrap(); 94 | /// println!("Sign H = {:?}", &h); 95 | /// println!("Sign S = {:?}", &s); 96 | /// 97 | /// let r = msk.verify_sign(&ida, &data, &h, &s); 98 | /// println!("VersionSign ={:?}", &r); 99 | /// } 100 | /// 101 | /// ``` 102 | /// 103 | /// 104 | /// ### key exchange 105 | /// ```rust 106 | /// use gm_sm9::key::{Sm9EncMasterKey,Sm9EncKey}; 107 | /// use gm_sm9::points::{Point, TwistPoint}; 108 | /// use gm_sm9::key::{exch_step_1a, exch_step_1b, exch_step_2a}; 109 | /// fn main() { 110 | /// let msk: Sm9EncMasterKey = Sm9EncMasterKey::master_key_generate(); 111 | /// let klen = 20usize; 112 | /// let ida = [0x41, 0x6C, 0x69, 0x63, 0x65u8]; 113 | /// let idb = [0x42, 0x6F, 0x62u8]; 114 | /// let key_a: Sm9EncKey = msk.extract_exch_key(&ida).unwrap(); 115 | /// let key_b: Sm9EncKey = msk.extract_exch_key(&idb).unwrap(); 116 | /// 117 | /// let (ra, ra_) = exch_step_1a(&msk, &idb); 118 | /// let (rb, skb) = exch_step_1b(&msk, &ida, &idb, &key_b, &ra, klen).unwrap(); 119 | /// let ska = exch_step_2a(&msk, &ida, &idb, &key_a, ra_, &ra, &rb, klen).unwrap(); 120 | /// println!("SKB = {:?}", &skb); 121 | /// println!("SKA = {:?}", &ska); 122 | /// for i in 0..klen { 123 | /// if ska[i] != skb[i] { 124 | /// println!("Exchange key different at byte index: {}", i) 125 | /// } 126 | /// } 127 | /// } 128 | /// 129 | /// ``` 130 | /// 131 | /// 132 | /// 133 | 134 | 135 | 136 | 137 | /// 本文使用256位的BN曲线。 138 | /// 139 | /// 椭圆曲线方程:y2 = x3 + b 140 | /// 141 | /// 参数 t: 60000000 0058F98A 142 | /// 143 | /// 基域特征 q(t) = 36t^4 + 36t^3 + 24t^2 + 6t + 1 144 | /// 145 | /// p = B6400000 02A3A6F1 D603AB4F F58EC745 21F2934B 1A7AEEDB E56F9B27 E351457D 146 | pub(crate) const SM9_P: U256 = [ 147 | 0xe56f9b27e351457d, 148 | 0x21f2934b1a7aeedb, 149 | 0xd603ab4ff58ec745, 150 | 0xb640000002a3a6f1, 151 | ]; 152 | 153 | pub(crate) const SM9_P_MINUS_ONE: U256 = [ 154 | 0xe56f9b27e351457c, 155 | 0x21f2934b1a7aeedb, 156 | 0xd603ab4ff58ec745, 157 | 0xb640000002a3a6f1, 158 | ]; 159 | 160 | /// e = p - 2 = b640000002a3a6f1d603ab4ff58ec74521f2934b1a7aeedbe56f9b27e351457b 161 | /// 162 | /// p - 2, used in a^(p-2) = a^-1 163 | pub(crate) const SM9_P_MINUS_TWO: U256 = [ 164 | 0xe56f9b27e351457b, 165 | 0x21f2934b1a7aeedb, 166 | 0xd603ab4ff58ec745, 167 | 0xb640000002a3a6f1, 168 | ]; 169 | 170 | /// p = b640000002a3a6f1d603ab4ff58ec74521f2934b1a7aeedbe56f9b27e351457d 171 | /// 172 | /// p' = -p^(-1) mod 2^256 = afd2bac5558a13b3966a4b291522b137181ae39613c8dbaf892bc42c2f2ee42b 173 | /// 174 | /// sage: -(IntegerModRing(2^256)(p))^-1 175 | pub(crate) const SM9_P_PRIME: U256 = [ 176 | 0x892bc42c2f2ee42b, 177 | 0x181ae39613c8dbaf, 178 | 0x966a4b291522b137, 179 | 0xafd2bac5558a13b3, 180 | ]; 181 | 182 | // mont params (mod p) 183 | // mu = p^-1 mod 2^64 = 0x76d43bd3d0d11bd5 184 | // 2^512 mod p = 0x2ea795a656f62fbde479b522d6706e7b88f8105fae1a5d3f27dea312b417e2d2 185 | // mont(1) mod p = 2^256 mod p = 0x49bffffffd5c590e29fc54b00a7138bade0d6cb4e58511241a9064d81caeba83 186 | pub(crate) const SM9_MODP_MU: u64 = 0x76d43bd3d0d11bd5_u64; 187 | pub(crate) const SM9_MODP_2E512: U256 = [ 188 | 0x27dea312b417e2d2, 189 | 0x88f8105fae1a5d3f, 190 | 0xe479b522d6706e7b, 191 | 0x2ea795a656f62fbd, 192 | ]; 193 | pub(crate) const SM9_MODP_MONT_ONE: U256 = [ 194 | 0x1a9064d81caeba83, 195 | 0xde0d6cb4e5851124, 196 | 0x29fc54b00a7138ba, 197 | 0x49bffffffd5c590e, 198 | ]; 199 | pub(crate) const SM9_MODP_MONT_FIVE: U256 = [ 200 | 0xb9f2c1e8c8c71995, 201 | 0x125df8f246a377fc, 202 | 0x25e650d049188d1c, 203 | 0x43fffffed866f63, 204 | ]; 205 | 206 | pub(crate) const SM9_MONT_ALPHA1: U256 = [ 207 | 0x1a98dfbd4575299f, 208 | 0x9ec8547b245c54fd, 209 | 0xf51f5eac13df846c, 210 | 0x9ef74015d5a16393, 211 | ]; 212 | 213 | pub(crate) const SM9_MONT_ALPHA2: U256 = [ 214 | 0xb626197dce4736ca, 215 | 0x08296b3557ed0186, 216 | 0x9c705db2fd91512a, 217 | 0x1c753e748601c992, 218 | ]; 219 | 220 | pub(crate) const SM9_MONT_ALPHA3: U256 = [ 221 | 0x39b4ef0f3ee72529, 222 | 0xdb043bf508582782, 223 | 0xb8554ab054ac91e3, 224 | 0x9848eec25498cab5, 225 | ]; 226 | 227 | pub(crate) const SM9_MONT_ALPHA4: U256 = [ 228 | 0x81054fcd94e9c1c4, 229 | 0x4c0e91cb8ce2df3e, 230 | 0x4877b452e8aedfb4, 231 | 0x88f53e748b491776, 232 | ]; 233 | 234 | pub(crate) const SM9_MONT_ALPHA5: U256 = [ 235 | 0x048baa79dcc34107, 236 | 0x5e2e7ac4fe76c161, 237 | 0x99399754365bd4bc, 238 | 0xaf91aeac819b0e13, 239 | ]; 240 | 241 | pub(crate) const SM9_MONT_BETA: Fp2 = Fp2 { 242 | c0: [ 243 | 0x39b4ef0f3ee72529, 244 | 0xdb043bf508582782, 245 | 0xb8554ab054ac91e3, 246 | 0x9848eec25498cab5, 247 | ], 248 | c1: [0, 0, 0, 0], 249 | }; 250 | 251 | pub(crate) const SM9_FP2_ZERO: [U256; 2] = [[0, 0, 0, 0], [0, 0, 0, 0]]; 252 | pub(crate) const SM9_FP2_ONE: [U256; 2] = [[1, 0, 0, 0], [0, 0, 0, 0]]; 253 | pub(crate) const SM9_FP2_U: [U256; 2] = [[0, 0, 0, 0], [1, 0, 0, 0]]; 254 | pub(crate) const SM9_FP2_5U: [U256; 2] = [[0, 0, 0, 0], [5, 0, 0, 0]]; 255 | pub(crate) const SM9_FP2_MONT_5U: [U256; 2] = [ 256 | [0, 0, 0, 0], 257 | [ 258 | 0xb9f2c1e8c8c71995, 259 | 0x125df8f246a377fc, 260 | 0x25e650d049188d1c, 261 | 0x43fffffed866f63, 262 | ], 263 | ]; 264 | 265 | pub(crate) const SM9_FP4_ZERO: [[U256; 2]; 2] = 266 | [[[0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0]]]; 267 | pub(crate) const SM9_FP4_MONT_ONE: [[U256; 2]; 2] = [ 268 | [ 269 | [ 270 | 0x1a9064d81caeba83, 271 | 0xde0d6cb4e5851124, 272 | 0x29fc54b00a7138ba, 273 | 0x49bffffffd5c590e, 274 | ], 275 | [0, 0, 0, 0], 276 | ], 277 | [[0, 0, 0, 0], [0, 0, 0, 0]], 278 | ]; 279 | 280 | /// 群的阶 N(t) = 36t^4 + 36t^3 + 18t^2 + 6t + 1 281 | /// 282 | /// n = B6400000 02A3A6F1 D603AB4F F58EC744 49F2934B 18EA8BEE E56EE19C D69ECF25 283 | pub(crate) const SM9_N: U256 = [ 284 | 0xe56ee19cd69ecf25, 285 | 0x49f2934b18ea8bee, 286 | 0xd603ab4ff58ec744, 287 | 0xb640000002a3a6f1, 288 | ]; 289 | 290 | /// 2^256 - n 291 | pub(crate) const SM9_N_NEG: U256 = [ 292 | 0x1a911e63296130db, 293 | 0xb60d6cb4e7157411, 294 | 0x29fc54b00a7138bb, 295 | 0x49bffffffd5c590e, 296 | ]; 297 | 298 | /// N - 1 299 | pub(crate) const SM9_N_MINUS_ONE: U256 = [ 300 | 0xe56ee19cd69ecf24, 301 | 0x49f2934b18ea8bee, 302 | 0xd603ab4ff58ec744, 303 | 0xb640000002a3a6f1, 304 | ]; 305 | 306 | /// N - 2 307 | pub(crate) const SM9_N_MINUS_TWO: U256 = [ 308 | 0xe56ee19cd69ecf23, 309 | 0x49f2934b18ea8bee, 310 | 0xd603ab4ff58ec744, 311 | 0xb640000002a3a6f1, 312 | ]; 313 | 314 | pub(crate) const SM9_N_BARRETT_MU: [u64; 5] = [ 315 | 0x74df4fd4dfc97c2f, 316 | 0x9c95d85ec9c073b0, 317 | 0x55f73aebdcd1312c, 318 | 0x67980e0beb5759a6, 319 | 0x1, 320 | ]; 321 | 322 | pub(crate) const SM9_U256_N_MINUS_ONE_BARRETT_MU: [u64; 4] = [ 323 | 0x74df4fd4dfc97c31, 324 | 0x9c95d85ec9c073b0, 325 | 0x55f73aebdcd1312c, 326 | 0x67980e0beb5759a6, 327 | ]; 328 | 329 | pub(crate) const SM9_HID_ENC: u8 = 0x03; 330 | pub(crate) const SM9_HID_EXCH: u8 = 0x02; 331 | pub(crate) const SM9_HID_SIGN: u8 = 0x01; 332 | 333 | pub(crate) const SM9_HASH1_PREFIX: u8 = 0x01; 334 | pub(crate) const SM9_HASH2_PREFIX: u8 = 0x02; 335 | 336 | pub(crate) const SM9_POINT_MONT_P1: Point = Point { 337 | x: [ 338 | 0x22e935e29860501b, 339 | 0xa946fd5e0073282c, 340 | 0xefd0cec817a649be, 341 | 0x5129787c869140b5, 342 | ], 343 | y: [ 344 | 0xee779649eb87f7c7, 345 | 0x15563cbdec30a576, 346 | 0x326353912824efbf, 347 | 0x7215717763c39828, 348 | ], 349 | z: [ 350 | 0x1a9064d81caeba83, 351 | 0xde0d6cb4e5851124, 352 | 0x29fc54b00a7138ba, 353 | 0x49bffffffd5c590e, 354 | ], 355 | }; 356 | 357 | pub(crate) const SM9_TWIST_POINT_MONT_P2: TwistPoint = TwistPoint { 358 | x: Fp2 { 359 | c0: [ 360 | 0x260226a68ce2da8f, 361 | 0x7ee5645edbf6c06b, 362 | 0xf8f57c82b1495444, 363 | 0x61fcf018bc47c4d1, 364 | ], 365 | c1: [ 366 | 0xdb6db4822750a8a6, 367 | 0x84c6135a5121f134, 368 | 0x1874032f88791d41, 369 | 0x905112f2b85f3a37, 370 | ], 371 | }, 372 | y: Fp2 { 373 | c0: [ 374 | 0xc03f138f9171c24a, 375 | 0x92fbab45a15a3ca7, 376 | 0x2445561e2ff77cdb, 377 | 0x108495e0c0f62ece, 378 | ], 379 | c1: [ 380 | 0xf7b82dac4c89bfbb, 381 | 0x3706f3f6a49dc12f, 382 | 0x1e29de93d3eef769, 383 | 0x81e448c3c76a5d53, 384 | ], 385 | }, 386 | z: Fp2 { 387 | c0: [ 388 | 0x1a9064d81caeba83, 389 | 0xde0d6cb4e5851124, 390 | 0x29fc54b00a7138ba, 391 | 0x49bffffffd5c590e, 392 | ], 393 | c1: [0, 0, 0, 0], 394 | }, 395 | }; 396 | 397 | -------------------------------------------------------------------------------- /gm-sm9/src/fields/fp12.rs: -------------------------------------------------------------------------------- 1 | use crate::fields::fp::Fp; 2 | use crate::fields::fp2::Fp2; 3 | use crate::fields::fp4::Fp4; 4 | use crate::fields::FieldElement; 5 | use crate::u256::{u256_cmp, U256}; 6 | use crate::{ 7 | SM9_MONT_ALPHA1, SM9_MONT_ALPHA2, SM9_MONT_ALPHA3, SM9_MONT_ALPHA4, SM9_MONT_ALPHA5, 8 | SM9_MONT_BETA, SM9_N_MINUS_ONE, 9 | }; 10 | 11 | #[derive(Debug, Copy, Clone)] 12 | pub struct Fp12 { 13 | pub(crate) c0: Fp4, 14 | pub(crate) c1: Fp4, 15 | pub(crate) c2: Fp4, 16 | } 17 | 18 | impl Fp12 { 19 | pub(crate) fn fp_line_mul(&self, lw: &[Fp2; 3]) -> Fp12 { 20 | let lw4 = Fp4 { 21 | c0: lw[0], 22 | c1: lw[2], 23 | }; 24 | 25 | let mut r0 = self.c0.fp_mul(&lw4); 26 | let mut r1 = self.c1.fp_mul(&lw4); 27 | let mut r2 = self.c2.fp_mul(&lw4); 28 | 29 | let mut t = self.c0.c0.fp_mul(&lw[1]); 30 | r2.c0 = r2.c0.fp_add(&t); 31 | 32 | t = self.c0.c1.fp_mul(&lw[1]); 33 | r2.c1 = r2.c1.fp_add(&t); 34 | 35 | t = self.c1.c0.fp_mul(&lw[1]); 36 | r0.c1 = r0.c1.fp_add(&t); 37 | 38 | t = self.c1.c1.fp_mul_u(&lw[1]); 39 | r0.c0 = r0.c0.fp_add(&t); 40 | 41 | t = self.c2.c0.fp_mul(&lw[1]); 42 | r1.c1 = r1.c1.fp_add(&t); 43 | 44 | t = self.c2.c1.fp_mul_u(&lw[1]); 45 | r1.c0 = r1.c0.fp_add(&t); 46 | Fp12 { 47 | c0: r0, 48 | c1: r1, 49 | c2: r2, 50 | } 51 | } 52 | 53 | pub(crate) fn fp12_frobenius6(&self) -> Fp12 { 54 | let (mut a, mut b, mut c) = (self.c0, self.c1, self.c2); 55 | a = a.conjugate(); 56 | b = b.conjugate(); 57 | b = b.fp_neg(); 58 | c = c.conjugate(); 59 | Fp12 { 60 | c0: a, 61 | c1: b, 62 | c2: c, 63 | } 64 | } 65 | 66 | pub(crate) fn fp12_frobenius2(&self) -> Fp12 { 67 | let (mut a, mut b, mut c) = (self.c0, self.c1, self.c2); 68 | a = a.conjugate(); 69 | b = b.conjugate(); 70 | b = b.fp_mul_fp(&SM9_MONT_ALPHA2); 71 | c = c.conjugate(); 72 | c = c.fp_mul_fp(&SM9_MONT_ALPHA4); 73 | Fp12 { 74 | c0: a, 75 | c1: b, 76 | c2: c, 77 | } 78 | } 79 | 80 | pub(crate) fn final_exponent_hard_part(&self) -> Fp12 { 81 | // a2 = 0xd8000000019062ed0000b98b0cb27659 82 | // a3 = 0x2400000000215d941 83 | let a2: Fp = [0x0000b98b0cb27659, 0xd8000000019062ed, 0, 0]; 84 | let a3: Fp = [0x400000000215d941, 0x2, 0, 0]; 85 | let nine: Fp = [9, 0, 0, 0]; 86 | 87 | let mut t0 = self.pow(&a3); 88 | t0 = t0.fp_inv(); 89 | let mut t1 = t0.fp12_frobenius(); 90 | t1 = t0.fp_mul(&t1); 91 | 92 | t0 = t0.fp_mul(&t1); 93 | let mut t2 = self.fp12_frobenius(); 94 | let mut t3 = t2.fp_mul(self); 95 | t3 = t3.pow(&nine); 96 | 97 | t0 = t0.fp_mul(&t3); 98 | t3 = self.fp_sqr(); 99 | t3 = t3.fp_sqr(); 100 | t0 = t0.fp_mul(&t3); 101 | t2 = t2.fp_sqr(); 102 | t2 = t2.fp_mul(&t1); 103 | 104 | t1 = self.fp12_frobenius2(); 105 | t1 = t1.fp_mul(&t2); 106 | 107 | t2 = t1.pow(&a2); 108 | t0 = t2.fp_mul(&t0); 109 | t1 = self.fp12_frobenius3(); 110 | t1 = t1.fp_mul(&t0); 111 | 112 | t1 113 | } 114 | 115 | pub(crate) fn final_exponent(&self) -> Fp12 { 116 | let mut t0 = self.fp12_frobenius6(); 117 | let mut t1 = self.fp_inv(); 118 | t0 = t0.fp_mul(&t1); 119 | t1 = t0.fp12_frobenius2(); 120 | t0 = t0.fp_mul(&t1); 121 | t0 = t0.final_exponent_hard_part(); 122 | t0 123 | } 124 | 125 | fn fp12_frobenius(&self) -> Self { 126 | let (a, b, c) = (self.c0, self.c1, self.c2); 127 | let (mut ra, mut rb, mut rc) = (Fp4::zero(), Fp4::zero(), Fp4::zero()); 128 | 129 | ra.c0 = a.c0.conjugate(); 130 | ra.c1 = a.c1.conjugate(); 131 | ra.c1 = ra.c1.fp_mul_fp(&SM9_MONT_ALPHA3); 132 | 133 | rb.c0 = b.c0.conjugate(); 134 | rb.c0 = rb.c0.fp_mul_fp(&SM9_MONT_ALPHA1); 135 | rb.c1 = b.c1.conjugate(); 136 | rb.c1 = rb.c1.fp_mul_fp(&SM9_MONT_ALPHA4); 137 | 138 | rc.c0 = c.c0.conjugate(); 139 | rc.c0 = rc.c0.fp_mul_fp(&SM9_MONT_ALPHA2); 140 | rc.c1 = c.c1.conjugate(); 141 | rc.c1 = rc.c1.fp_mul_fp(&SM9_MONT_ALPHA5); 142 | 143 | Self { 144 | c0: ra, 145 | c1: rb, 146 | c2: rc, 147 | } 148 | } 149 | 150 | fn fp12_frobenius3(&self) -> Self { 151 | let (a, b, c) = (self.c0, self.c1, self.c2); 152 | let (mut ra, mut rb, mut rc) = (Fp4::zero(), Fp4::zero(), Fp4::zero()); 153 | 154 | ra.c0 = a.c0.conjugate(); 155 | ra.c1 = a.c1.conjugate(); 156 | ra.c1 = ra.c1.fp_mul(&SM9_MONT_BETA); 157 | ra.c1 = ra.c1.fp_neg(); 158 | 159 | rb.c0 = b.c0.conjugate(); 160 | rb.c0 = rb.c0.fp_mul(&SM9_MONT_BETA); 161 | rb.c1 = b.c1.conjugate(); 162 | 163 | rc.c0 = c.c0.conjugate(); 164 | rc.c0 = rc.c0.fp_neg(); 165 | rc.c1 = c.c1.conjugate(); 166 | rc.c1 = rc.c1.fp_mul(&SM9_MONT_BETA); 167 | Self { 168 | c0: ra, 169 | c1: rb, 170 | c2: rc, 171 | } 172 | } 173 | } 174 | 175 | impl PartialEq for Fp12 { 176 | fn eq(&self, other: &Self) -> bool { 177 | self.c0.eq(&other.c0) && self.c1.eq(&other.c1) && self.c2.eq(&other.c2) 178 | } 179 | } 180 | 181 | impl Eq for Fp12 {} 182 | 183 | impl FieldElement for Fp12 { 184 | fn zero() -> Self { 185 | Self { 186 | c0: Fp4::zero(), 187 | c1: Fp4::zero(), 188 | c2: Fp4::zero(), 189 | } 190 | } 191 | 192 | fn one() -> Self { 193 | Self { 194 | c0: Fp4::one(), 195 | c1: Fp4::zero(), 196 | c2: Fp4::zero(), 197 | } 198 | } 199 | 200 | fn is_zero(&self) -> bool { 201 | self.c0.is_zero() && self.c1.is_zero() && self.c2.is_zero() 202 | } 203 | 204 | fn fp_sqr(&self) -> Self { 205 | let mut r2 = Fp4::zero(); 206 | let mut s2 = Fp4::zero(); 207 | let mut s3 = Fp4::zero(); 208 | 209 | let mut r0 = self.c0.fp_sqr(); 210 | let mut r1 = self.c2.fp_sqr(); 211 | let mut s0 = self.c2.fp_add(&self.c0); 212 | 213 | let mut t = s0.fp_sub(&self.c1); 214 | let s1 = t.fp_sqr(); 215 | 216 | t = s0.fp_add(&self.c1); 217 | s0 = t.fp_sqr(); 218 | 219 | s2 = self.c1.fp_mul(&self.c2); 220 | s2 = s2.fp_double(); 221 | 222 | s3 = s0.fp_add(&s1); 223 | s3 = s3.fp_div2(); 224 | 225 | t = s3.fp_sub(&r1); 226 | r2 = t.fp_sub(&r0); 227 | 228 | r1 = r1.a_mul_v(); 229 | r1 = r1.fp_add(&s0); 230 | r1 = r1.fp_sub(&s2); 231 | r1 = r1.fp_sub(&s3); 232 | 233 | s2 = s2.a_mul_v(); 234 | r0 = r0.fp_add(&s2); 235 | 236 | Self { 237 | c0: r0, 238 | c1: r1, 239 | c2: r2, 240 | } 241 | } 242 | 243 | fn fp_double(&self) -> Self { 244 | Self { 245 | c0: self.c0.fp_double(), 246 | c1: self.c1.fp_double(), 247 | c2: self.c2.fp_double(), 248 | } 249 | } 250 | 251 | fn fp_triple(&self) -> Self { 252 | let t = self.fp_double(); 253 | t.fp_add(self) 254 | } 255 | 256 | fn fp_add(&self, rhs: &Self) -> Self { 257 | Self { 258 | c0: self.c0.fp_add(&rhs.c0), 259 | c1: self.c1.fp_add(&rhs.c1), 260 | c2: self.c2.fp_add(&rhs.c2), 261 | } 262 | } 263 | 264 | fn fp_sub(&self, rhs: &Self) -> Self { 265 | Self { 266 | c0: self.c0.fp_sub(&rhs.c0), 267 | c1: self.c1.fp_sub(&rhs.c1), 268 | c2: self.c2.fp_sub(&rhs.c2), 269 | } 270 | } 271 | 272 | fn fp_mul(&self, rhs: &Self) -> Self { 273 | let (mut r0, mut r1, mut r2) = (Fp4::zero(), Fp4::zero(), Fp4::zero()); 274 | let (mut t, mut k0, mut k1) = (Fp4::zero(), Fp4::zero(), Fp4::zero()); 275 | let (mut m0, mut m1, mut m2) = (Fp4::zero(), Fp4::zero(), Fp4::zero()); 276 | 277 | m0 = self.c0.fp_mul(&rhs.c0); 278 | m1 = self.c1.fp_mul(&rhs.c1); 279 | m2 = self.c2.fp_mul(&rhs.c2); 280 | 281 | k0 = self.c1.fp_add(&self.c2); 282 | k1 = rhs.c1.fp_add(&rhs.c2); 283 | t = k0.fp_mul(&k1); 284 | t = t.fp_sub(&m1); 285 | t = t.fp_sub(&m2); 286 | t = t.a_mul_v(); 287 | r0 = t.fp_add(&m0); 288 | 289 | k0 = self.c0.fp_add(&self.c2); 290 | k1 = rhs.c0.fp_add(&rhs.c2); 291 | t = k0.fp_mul(&k1); 292 | t = t.fp_sub(&m0); 293 | t = t.fp_sub(&m2); 294 | r2 = t.fp_add(&m1); 295 | 296 | k0 = self.c0.fp_add(&self.c1); 297 | k1 = rhs.c0.fp_add(&rhs.c1); 298 | t = k0.fp_mul(&k1); 299 | t = t.fp_sub(&m0); 300 | t = t.fp_sub(&m1); 301 | m2 = m2.a_mul_v(); 302 | r1 = t.fp_add(&m2); 303 | 304 | Self { 305 | c0: r0, 306 | c1: r1, 307 | c2: r2, 308 | } 309 | } 310 | 311 | fn fp_neg(&self) -> Self { 312 | Self { 313 | c0: self.c0.fp_neg(), 314 | c1: self.c1.fp_neg(), 315 | c2: self.c2.fp_neg(), 316 | } 317 | } 318 | 319 | fn fp_div2(&self) -> Self { 320 | Self { 321 | c0: self.c0.fp_div2(), 322 | c1: self.c1.fp_div2(), 323 | c2: self.c2.fp_div2(), 324 | } 325 | } 326 | 327 | fn fp_inv(&self) -> Self { 328 | if self.c2.is_zero() { 329 | let mut r = Fp12::zero(); 330 | let mut k = Fp4::zero(); 331 | let mut t = Fp4::zero(); 332 | 333 | k = self.c0.fp_sqr(); 334 | k = k.fp_mul(&self.c0); 335 | t = self.c1.sqr_v(); 336 | t = t.fp_mul(&self.c1); 337 | k = k.fp_add(&t); 338 | k = k.fp_inv(); 339 | 340 | r.c2 = self.c1.fp_sqr(); 341 | r.c2 = r.c2.fp_mul(&k); 342 | 343 | r.c1 = self.c0.fp_mul(&self.c1); 344 | r.c1 = r.c1.fp_mul(&k); 345 | r.c1 = r.c1.fp_neg(); 346 | 347 | r.c0 = self.c0.fp_sqr(); 348 | r.c0 = r.c0.fp_mul(&k); 349 | r 350 | } else { 351 | let mut r = Fp12::zero(); 352 | let mut t0 = Fp4::zero(); 353 | let mut t1 = Fp4::zero(); 354 | let mut t2 = Fp4::zero(); 355 | let mut t3 = Fp4::zero(); 356 | 357 | t0 = self.c1.fp_sqr(); 358 | t1 = self.c0.fp_mul(&self.c2); 359 | t0 = t0.fp_sub(&t1); 360 | 361 | t1 = self.c0.fp_mul(&self.c1); 362 | t2 = self.c2.sqr_v(); 363 | t1 = t1.fp_sub(&t2); 364 | 365 | t2 = self.c0.fp_sqr(); 366 | t3 = self.c1.fp_mul_v(&self.c2); 367 | t2 = t2.fp_sub(&t3); 368 | 369 | t3 = t1.fp_sqr(); 370 | r.c0 = t0.fp_mul(&t2); 371 | t3 = t3.fp_sub(&r.c0); 372 | t3 = t3.fp_inv(); 373 | t3 = self.c2.fp_mul(&t3); 374 | 375 | r.c0 = t2.fp_mul(&t3); 376 | 377 | r.c1 = t1.fp_mul(&t3); 378 | r.c1 = r.c1.fp_neg(); 379 | 380 | r.c2 = t0.fp_mul(&t3); 381 | r 382 | } 383 | } 384 | 385 | fn to_bytes_be(&self) -> Vec { 386 | let mut bytes: Vec = vec![]; 387 | bytes.extend_from_slice(self.c2.to_bytes_be().as_slice()); 388 | bytes.extend_from_slice(self.c1.to_bytes_be().as_slice()); 389 | bytes.extend_from_slice(self.c0.to_bytes_be().as_slice()); 390 | bytes 391 | } 392 | } 393 | 394 | impl Fp12 { 395 | pub(crate) fn pow(&self, e: &U256) -> Self { 396 | assert!(u256_cmp(e, &SM9_N_MINUS_ONE) < 0); 397 | let mut w = 0_u64; 398 | let mut t = Fp12 { 399 | c0: Fp4::mont_one(), 400 | c1: Fp4::zero(), 401 | c2: Fp4::zero(), 402 | }; 403 | 404 | for i in (0..4).rev() { 405 | w = e[i]; 406 | for j in 0..64 { 407 | t = t.fp_sqr(); 408 | if w & 0x8000000000000000 != 0 { 409 | t = t.fp_mul(self) 410 | } 411 | w <<= 1; 412 | } 413 | } 414 | t 415 | } 416 | } 417 | -------------------------------------------------------------------------------- /gm-sm2/src/key.rs: -------------------------------------------------------------------------------- 1 | use hex::{FromHexError, ToHex}; 2 | use num_bigint::BigUint; 3 | 4 | use gm_sm3::sm3_hash; 5 | 6 | use crate::error::{Sm2Error, Sm2Result}; 7 | use crate::fields::FieldModOperation; 8 | use crate::fields::fn64::{fn_add, fn_mul, fn_pow, fn_sub, SM2_N, SM2_N_MINUS_TWO}; 9 | use crate::fields::fp64::{fp_from_mont, random_u256}; 10 | use crate::p256_ecc::{g_mul, Point}; 11 | use crate::u256::{SM2_ONE, U256, u256_add, u256_cmp, u256_from_be_bytes}; 12 | use crate::util::{compute_za, DEFAULT_ID, kdf, xor_bytes}; 13 | 14 | pub enum Sm2Model { 15 | C1C2C3, 16 | C1C3C2, 17 | } 18 | 19 | #[derive(Debug, Clone, Copy)] 20 | pub struct Sm2PublicKey { 21 | pub point: Point, 22 | } 23 | 24 | impl Sm2PublicKey { 25 | pub fn to_bytes(&self, compress: bool) -> Vec { 26 | self.point.to_byte_be(compress) 27 | } 28 | 29 | pub fn new(pk: &[u8]) -> Sm2Result { 30 | let p = Point::from_byte(pk)?; 31 | if p.is_valid() { 32 | Ok(Self { point: p }) 33 | } else { 34 | Err(Sm2Error::InvalidPublic) 35 | } 36 | } 37 | 38 | pub fn is_valid(&self) -> bool { 39 | self.point.is_valid() 40 | } 41 | 42 | /// Encrypt the given message and return ASN.1 data 43 | pub fn encrypt_asn1( 44 | &self, 45 | msg: &[u8], 46 | compressed: bool, 47 | model: Sm2Model, 48 | ) -> Sm2Result> { 49 | let cipher = self.encrypt(msg, compressed, model).unwrap(); 50 | let x = BigUint::from_bytes_be(&cipher[0..32]); 51 | let y = BigUint::from_bytes_be(&cipher[32..64]); 52 | let sm3 = &cipher[64..96]; 53 | let secret = &cipher[96..]; 54 | Ok(yasna::construct_der(|writer| { 55 | writer.write_sequence(|writer| { 56 | writer.next().write_biguint(&x); 57 | writer.next().write_biguint(&y); 58 | writer.next().write_bytes(&sm3); 59 | writer.next().write_bytes(&secret); 60 | }); 61 | })) 62 | } 63 | 64 | /// Encrypt the given message. 65 | pub fn encrypt(&self, msg: &[u8], compressed: bool, model: Sm2Model) -> Sm2Result> { 66 | loop { 67 | let klen = msg.len(); 68 | let k = random_u256(); 69 | let c1_p = g_mul(&k); 70 | let c1_p = c1_p.to_affine_point(); // 根据加密算法,z坐标会被丢弃,为保证解密还原回来的坐标在曲线上,则必须转换坐标系到 affine 坐标系 71 | 72 | let s_p = self.point.scalar_mul(&SM2_ONE); 73 | if s_p.is_zero() { 74 | return Err(Sm2Error::ZeroPoint); 75 | } 76 | 77 | let c2_p = self.point.scalar_mul(&k).to_affine_point(); 78 | let x2_bytes = fp_from_mont(&c2_p.x).to_byte_be(); 79 | let y2_bytes = fp_from_mont(&c2_p.y).to_byte_be(); 80 | let mut c2_append = vec![]; 81 | c2_append.extend_from_slice(&x2_bytes); 82 | c2_append.extend_from_slice(&y2_bytes); 83 | 84 | let t = kdf(&c2_append[..], klen); 85 | let mut flag = true; 86 | for elem in &t { 87 | if elem != &0 { 88 | flag = false; 89 | break; 90 | } 91 | } 92 | if !flag { 93 | let c2 = xor_bytes(msg, &t[..]); 94 | let mut c3_append: Vec = vec![]; 95 | c3_append.extend_from_slice(&x2_bytes); 96 | c3_append.extend_from_slice(msg); 97 | c3_append.extend_from_slice(&y2_bytes); 98 | let c3 = sm3_hash(&c3_append); 99 | let mut c: Vec = vec![]; 100 | match model { 101 | Sm2Model::C1C2C3 => { 102 | c.extend_from_slice(&c1_p.to_byte_be(compressed)); 103 | c.extend_from_slice(&c2); 104 | c.extend_from_slice(&c3); 105 | } 106 | Sm2Model::C1C3C2 => { 107 | c.extend_from_slice(&c1_p.to_byte_be(compressed)); 108 | c.extend_from_slice(&c3); 109 | c.extend_from_slice(&c2); 110 | } 111 | } 112 | return Ok(c); 113 | } 114 | } 115 | } 116 | 117 | pub fn verify(&self, id: Option<&'static str>, msg: &[u8], sig: &[u8]) -> Sm2Result<()> { 118 | let id = id.unwrap_or_else(|| DEFAULT_ID); 119 | let mut digest = compute_za(id, &self.point)?; 120 | digest = sm3_hash(&[digest.to_vec(), msg.to_vec()].concat()); 121 | self.verify_raw(&digest[..], &self.point, sig) 122 | } 123 | 124 | fn verify_raw(&self, digest: &[u8], pk: &Point, sig: &[u8]) -> Sm2Result<()> { 125 | if digest.len() != 32 { 126 | return Err(Sm2Error::InvalidDigestLen); 127 | } 128 | let n = &SM2_N; 129 | let r = &u256_from_be_bytes(&sig[..32]); 130 | let s = &u256_from_be_bytes(&sig[32..]); 131 | if r.is_zero() || s.is_zero() { 132 | return Err(Sm2Error::ZeroSig); 133 | } 134 | if u256_cmp(r, n) >= 0 || u256_cmp(s, n) >= 0 { 135 | return Err(Sm2Error::InvalidDigest); 136 | } 137 | let t = fn_add(&s, &r); 138 | if t.is_zero() { 139 | return Err(Sm2Error::InvalidDigest); 140 | } 141 | let s_g = g_mul(&s); 142 | let t_p = pk.scalar_mul(&t); 143 | let p = s_g.point_add(&t_p).to_affine_point(); 144 | let x1 = u256_from_be_bytes(&fp_from_mont(&p.x).to_byte_be()); 145 | let e = u256_from_be_bytes(&digest); 146 | let r1 = fn_add(&x1, &e); 147 | return if u256_cmp(r, &r1) == 0 { 148 | Ok(()) 149 | } else { 150 | Err(Sm2Error::InvalidDigest) 151 | }; 152 | } 153 | 154 | pub fn to_hex_string(&self, compressed: bool) -> String { 155 | let bytes = self.to_bytes(compressed); 156 | bytes.encode_hex::() 157 | } 158 | 159 | pub fn from_hex_string(hex_str: &str) -> Result { 160 | let bytes = hex::decode(hex_str); 161 | match bytes { 162 | Ok(b) => Ok(Self { 163 | point: Point::from_byte(b.as_slice()).unwrap(), 164 | }), 165 | Err(e) => Err(e), 166 | } 167 | } 168 | 169 | pub fn value(&self) -> &Point { 170 | &self.point 171 | } 172 | } 173 | 174 | #[derive(Debug, Clone)] 175 | pub struct Sm2PrivateKey { 176 | pub d: U256, 177 | pub public_key: Sm2PublicKey, 178 | } 179 | 180 | impl Eq for Sm2PrivateKey {} 181 | 182 | impl PartialEq for Sm2PrivateKey { 183 | #[inline] 184 | fn eq(&self, other: &Sm2PrivateKey) -> bool { 185 | self.d == other.d 186 | } 187 | } 188 | 189 | impl AsRef for Sm2PrivateKey { 190 | fn as_ref(&self) -> &Sm2PublicKey { 191 | &self.public_key 192 | } 193 | } 194 | 195 | impl Sm2PrivateKey { 196 | pub fn new(sk: &[u8]) -> Sm2Result { 197 | let d = u256_from_be_bytes(sk); 198 | let public_key = public_from_private(&d)?; 199 | let private_key = Self { d, public_key }; 200 | Ok(private_key) 201 | } 202 | 203 | #[inline] 204 | pub fn to_bytes_be(&self) -> Vec { 205 | self.d.to_byte_be() 206 | } 207 | 208 | /// Sign the given digest. 209 | pub fn sign(&self, id: Option<&'static str>, msg: &[u8]) -> Sm2Result> { 210 | let id = id.unwrap_or_else(|| DEFAULT_ID); 211 | let mut digest = compute_za(id, &self.public_key.point)?; 212 | digest = sm3_hash(&[digest.to_vec(), msg.to_vec()].concat()); 213 | self.sign_raw(&digest[..], &self.d) 214 | } 215 | 216 | fn sign_raw(&self, digest: &[u8], sk: &U256) -> Sm2Result> { 217 | if digest.len() != 32 { 218 | return Err(Sm2Error::InvalidDigestLen); 219 | } 220 | let e = u256_from_be_bytes(&digest); 221 | let n = &SM2_N; 222 | let s1 = fn_pow(&u256_add(&SM2_ONE, &sk).0, &SM2_N_MINUS_TWO); 223 | loop { 224 | let k = random_u256(); 225 | let p_x = g_mul(&k).to_affine_point(); 226 | let x1 = u256_from_be_bytes(&fp_from_mont(&p_x.x).to_byte_be()); 227 | let r = fn_add(&e, &x1); 228 | if r.is_zero() || u256_add(&r, &k).0 == *n { 229 | continue; 230 | } 231 | let s2_1 = fn_mul(&r, &sk); 232 | let s2 = fn_sub(&k, &s2_1); 233 | let s = fn_mul(&s1, &s2); 234 | if s.is_zero() { 235 | continue; 236 | } 237 | let mut sig: Vec = vec![]; 238 | sig.extend_from_slice(&r.to_byte_be()); 239 | sig.extend_from_slice(&s.to_byte_be()); 240 | return Ok(sig); 241 | } 242 | } 243 | 244 | /// Decrypt the given ASN.1 message. 245 | pub fn decrypt_asn1( 246 | &self, 247 | ciphertext: &[u8], 248 | compressed: bool, 249 | model: Sm2Model, 250 | ) -> Sm2Result> { 251 | let (x, y, sm3, secret) = yasna::parse_der(ciphertext, |reader| { 252 | reader.read_sequence(|reader| { 253 | let x = reader.next().read_biguint()?; 254 | let y = reader.next().read_biguint()?; 255 | let sm3 = reader.next().read_bytes()?; 256 | let secret = reader.next().read_bytes()?; 257 | return Ok((x, y, sm3, secret)); 258 | }) 259 | }) 260 | .unwrap(); 261 | let x = BigUint::to_bytes_be(&x); 262 | let y = BigUint::to_bytes_be(&y); 263 | let mut cipher: Vec = vec![]; 264 | cipher.extend_from_slice(&x); 265 | cipher.extend_from_slice(&y); 266 | cipher.extend_from_slice(&sm3); 267 | cipher.extend_from_slice(&secret); 268 | self.decrypt(&cipher, compressed, model) 269 | } 270 | 271 | /// Decrypt the given message. 272 | pub fn decrypt( 273 | &self, 274 | ciphertext: &[u8], 275 | compressed: bool, 276 | model: Sm2Model, 277 | ) -> Sm2Result> { 278 | let c1_end_index = match compressed { 279 | true => 33, 280 | false => 65, 281 | }; 282 | let c1_bytes = &ciphertext[0..c1_end_index]; 283 | let len = ciphertext.len(); 284 | let c2_bytes = match model { 285 | Sm2Model::C1C2C3 => &ciphertext[c1_end_index..(len - 32)], 286 | Sm2Model::C1C3C2 => &ciphertext[(c1_end_index + 32)..], 287 | }; 288 | let c3_bytes = match model { 289 | Sm2Model::C1C2C3 => &ciphertext[(len - 32)..], 290 | Sm2Model::C1C3C2 => &ciphertext[c1_end_index..c1_end_index + 32], 291 | }; 292 | 293 | let kelen = c2_bytes.len(); 294 | let c1_point = Point::from_byte(c1_bytes)?; 295 | if !c1_point.to_affine_point().is_valid_affine_point() { 296 | return Err(Sm2Error::CheckPointErr); 297 | } 298 | 299 | let s_point = c1_point.scalar_mul(&SM2_ONE); 300 | if s_point.is_zero() { 301 | return Err(Sm2Error::ZeroPoint); 302 | } 303 | 304 | let c2_point = c1_point.scalar_mul(&self.d).to_affine_point(); 305 | let x2_bytes = fp_from_mont(&c2_point.x).to_byte_be(); 306 | let y2_bytes = fp_from_mont(&c2_point.y).to_byte_be(); 307 | let mut prepend: Vec = vec![]; 308 | prepend.extend_from_slice(&x2_bytes); 309 | prepend.extend_from_slice(&y2_bytes); 310 | let t = kdf(&prepend, kelen); 311 | let mut flag = true; 312 | for elem in &t { 313 | if elem != &0 { 314 | flag = false; 315 | break; 316 | } 317 | } 318 | if flag { 319 | return Err(Sm2Error::ZeroData); 320 | } 321 | 322 | let m = xor_bytes(c2_bytes, &t); 323 | let mut mb = m; 324 | if mb.len() < kelen { 325 | for i in 0..kelen - mb.len() { 326 | mb.insert(i, 0); 327 | } 328 | } 329 | let mut prepend: Vec = vec![]; 330 | prepend.extend_from_slice(&x2_bytes); 331 | prepend.extend_from_slice(&mb); 332 | prepend.extend_from_slice(&y2_bytes); 333 | let u = sm3_hash(&prepend); 334 | if u != c3_bytes { 335 | return Err(Sm2Error::HashNotEqual); 336 | } 337 | Ok(mb) 338 | } 339 | 340 | pub fn to_hex_string(&self) -> String { 341 | let bytes = self.d.to_byte_be(); 342 | bytes.encode_hex::() 343 | } 344 | 345 | pub fn from_hex_string(hex_str: &str) -> Result { 346 | let bytes = hex::decode(hex_str); 347 | match bytes { 348 | Ok(b) => { 349 | let r = Self::new(b.as_slice()); 350 | match r { 351 | Ok(sk) => Ok(sk), 352 | Err(e) => Err(e.to_string()), 353 | } 354 | } 355 | Err(e) => Err(e.to_string()), 356 | } 357 | } 358 | 359 | pub fn to_public_key(&self) -> Sm2PublicKey { 360 | self.public_key.clone() 361 | } 362 | } 363 | 364 | /// generate key pair 365 | pub fn gen_keypair() -> Sm2Result<(Sm2PublicKey, Sm2PrivateKey)> { 366 | let d = random_u256(); 367 | let pk = public_from_private(&d)?; 368 | let sk = Sm2PrivateKey { d, public_key: pk }; 369 | Ok((pk, sk)) 370 | } 371 | 372 | fn public_from_private(sk: &U256) -> Sm2Result { 373 | let p = g_mul(&sk); 374 | if p.is_valid() { 375 | Ok(Sm2PublicKey { point: p }) 376 | } else { 377 | Err(Sm2Error::InvalidPublic) 378 | } 379 | } 380 | -------------------------------------------------------------------------------- /gm-sm2/src/p256_ecc.rs: -------------------------------------------------------------------------------- 1 | use crate::error::{Sm2Error, Sm2Result}; 2 | use crate::fields::fp64::{fp_sqrt, fp_from_mont, fp_to_mont, SM2_P}; 3 | use crate::fields::FieldModOperation; 4 | use crate::sm2p256_table::SM2P256_PRECOMPUTED; 5 | use crate::u256::{u256_from_be_bytes, SM2_ZERO, U256}; 6 | 7 | #[derive(Debug, Clone, Eq, PartialEq, Copy)] 8 | pub struct Point { 9 | pub x: U256, 10 | pub y: U256, 11 | pub z: U256, 12 | } 13 | 14 | impl Point { 15 | pub fn zero() -> Point { 16 | Point { 17 | x: crate::fields::fp64::SM2_MODP_MONT_ONE, 18 | y: crate::fields::fp64::SM2_MODP_MONT_ONE, 19 | z: SM2_ZERO, 20 | } 21 | } 22 | 23 | pub fn is_zero(&self) -> bool { 24 | self.z == [0; 4] 25 | } 26 | 27 | pub fn is_valid(&self) -> bool { 28 | if self.is_zero() { 29 | true 30 | } else { 31 | // y^2 = x * (x^2 + a * z^4) + b * z^6 32 | let yy = self.y.fp_sqr(); 33 | let xx = self.x.fp_sqr(); 34 | let z2 = self.z.fp_sqr(); 35 | let z4 = z2.fp_sqr(); 36 | let z6 = z4.fp_mul(&z2); 37 | let z6_b = z6.fp_mul(&crate::fields::fp64::SM2_MODP_MONT_B); 38 | let a_z4 = z4.fp_mul(&crate::fields::fp64::SM2_MODP_MONT_A); 39 | 40 | let xx_a_4z = xx.fp_add(&a_z4); 41 | let xxx_a_4z = xx_a_4z.fp_mul(&self.x); 42 | let exp = xxx_a_4z.fp_add(&z6_b); 43 | yy.eq(&exp) 44 | } 45 | } 46 | 47 | pub fn is_valid_affine_point(&self) -> bool { 48 | // y^2 = x * (x^2 + a) + b 49 | let yy = self.y.fp_sqr(); 50 | let xx = self.x.fp_sqr(); 51 | let xx_a = xx.fp_add(&crate::fields::fp64::SM2_MODP_MONT_A); 52 | let xxx_a = self.x.fp_mul(&xx_a); 53 | let exp = xxx_a.fp_add(&crate::fields::fp64::SM2_MODP_MONT_B); 54 | yy.eq(&exp) 55 | } 56 | 57 | pub fn to_affine_point(&self) -> Point { 58 | let z_inv = self.z.fp_inv(); 59 | let z_inv2 = z_inv.fp_sqr(); 60 | let z_inv3 = z_inv2.fp_mul(&z_inv); 61 | let x = self.x.fp_mul(&z_inv2); 62 | let y = self.y.fp_mul(&z_inv3); 63 | Point { 64 | x, 65 | y, 66 | z: crate::fields::fp64::SM2_MODP_MONT_ONE, 67 | } 68 | } 69 | 70 | pub fn to_byte_be(&self, compress: bool) -> Vec { 71 | let p_affine = self.to_affine_point(); 72 | let mut x_vec = fp_from_mont(&p_affine.x).to_byte_be(); 73 | let mut y_vec = fp_from_mont(&p_affine.y).to_byte_be(); 74 | let mut ret: Vec = Vec::new(); 75 | if compress { 76 | if y_vec[y_vec.len() - 1] & 0x01 == 0 { 77 | ret.push(0x02); 78 | } else { 79 | ret.push(0x03); 80 | } 81 | ret.append(&mut x_vec); 82 | } else { 83 | ret.push(0x04); 84 | ret.append(&mut x_vec); 85 | ret.append(&mut y_vec); 86 | } 87 | ret 88 | } 89 | 90 | pub(crate) fn from_byte(b: &[u8]) -> Sm2Result { 91 | let flag = b[0]; 92 | // Compressed Point 93 | if flag == 0x02 || flag == 0x03 { 94 | if b.len() != 33 { 95 | return Err(Sm2Error::InvalidPublic); 96 | } 97 | let y_q; 98 | if b[0] == 0x02 { 99 | y_q = 0; 100 | } else { 101 | y_q = 1 102 | } 103 | let x = fp_to_mont(&U256::from_byte_be(&b[1..])); 104 | let xxx = x.fp_mul(&x).fp_mul(&x); 105 | let ax = x.fp_mul(&crate::fields::fp64::SM2_MODP_MONT_A); 106 | let yy = xxx 107 | .fp_add(&ax) 108 | .fp_add(&crate::fields::fp64::SM2_MODP_MONT_B); 109 | 110 | let mut y = fp_sqrt(&yy)?; 111 | let y_vec = fp_from_mont(&y).to_byte_be(); 112 | if y_vec[y_vec.len() - 1] & 0x01 != y_q { 113 | y = SM2_P.fp_sub(&y); 114 | } 115 | Ok(Point { 116 | x, 117 | y, 118 | z: crate::fields::fp64::SM2_MODP_MONT_ONE, 119 | }) 120 | } 121 | // uncompressed Point 122 | else { 123 | if b.len() != 65 { 124 | return Err(Sm2Error::InvalidPublic); 125 | } 126 | let x = fp_to_mont(&u256_from_be_bytes(&b[1..33])); 127 | let y = fp_to_mont(&u256_from_be_bytes(&b[33..65])); 128 | Ok(Point { 129 | x, 130 | y, 131 | z: crate::fields::fp64::SM2_MODP_MONT_ONE, 132 | }) 133 | } 134 | } 135 | 136 | pub fn neg(&self) -> Point { 137 | Point { 138 | x: self.x.clone(), 139 | y: SM2_P.fp_sub(&self.y), 140 | z: self.z.clone(), 141 | } 142 | } 143 | 144 | pub fn point_add(&self, p: &Point) -> Point { 145 | // 0 + p2 = p2 146 | if self.is_zero() { 147 | return p.clone(); 148 | } 149 | // p1 + 0 = p1 150 | if p.is_zero() { 151 | return self.clone(); 152 | } 153 | 154 | let x1 = self.x; 155 | let y1 = self.y; 156 | let z1 = self.z; 157 | 158 | let x2 = p.x; 159 | let y2 = p.y; 160 | let z2 = p.z; 161 | 162 | // p1 = p2 163 | if x1 == x2 && y1 == y2 && z1 == z2 { 164 | return self.point_dbl(); 165 | } else { 166 | let z1_sqr = z1.fp_sqr(); 167 | let z2_sqr = z2.fp_sqr(); 168 | let u1 = x1.fp_mul(&z2_sqr); 169 | let u2 = x2.fp_mul(&z1_sqr); 170 | let y1_z2 = y1.fp_mul(&z2); 171 | let s1 = y1_z2.fp_mul(&z2_sqr); 172 | let y2_z1 = y2.fp_mul(&z1); 173 | let s2 = y2_z1.fp_mul(&z1_sqr); 174 | let h = u2.fp_sub(&u1); 175 | let r = s2.fp_sub(&s1); 176 | let hh = h.fp_sqr(); 177 | let hhh = hh.fp_mul(&h); 178 | let v = u1.fp_mul(&hh); 179 | let r_sqr = r.fp_sqr(); 180 | let r_sqr_hhh = r_sqr.fp_sub(&hhh); 181 | let x3 = r_sqr_hhh.fp_sub(&v.fp_double()); 182 | let v_x3 = v.fp_sub(&x3); 183 | let r_v_x3 = r.fp_mul(&v_x3); 184 | let s1_hhh = s1.fp_mul(&hhh); 185 | let y3 = r_v_x3.fp_sub(&s1_hhh); 186 | let z3 = z1.fp_mul(&z2).fp_mul(&h); 187 | Point { 188 | x: x3, 189 | y: y3, 190 | z: z3, 191 | } 192 | } 193 | } 194 | 195 | // P = [k]G 196 | pub fn scalar_mul(&self, scalar: &[u64]) -> Point { 197 | let mut pre_table = vec![]; 198 | for _ in 0..16 { 199 | pre_table.push(Point::zero()); 200 | } 201 | 202 | let mut r = Point::zero(); 203 | pre_table[1 - 1] = *self; 204 | pre_table[2 - 1] = pre_table[1 - 1].point_dbl(); 205 | pre_table[4 - 1] = pre_table[2 - 1].point_dbl(); 206 | pre_table[8 - 1] = pre_table[4 - 1].point_dbl(); 207 | pre_table[3 - 1] = pre_table[1 - 1].point_add(&pre_table[2 - 1]); 208 | pre_table[6 - 1] = pre_table[3 - 1].point_dbl(); 209 | pre_table[7 - 1] = pre_table[1 - 1].point_add(&pre_table[6 - 1]); 210 | pre_table[12 - 1] = pre_table[6 - 1].point_dbl(); 211 | pre_table[5 - 1] = pre_table[1 - 1].point_add(&pre_table[4 - 1]); 212 | pre_table[10 - 1] = pre_table[5 - 1].point_dbl(); 213 | pre_table[14 - 1] = pre_table[7 - 1].point_dbl(); 214 | pre_table[9 - 1] = pre_table[1 - 1].point_add(&pre_table[8 - 1]); 215 | pre_table[11 - 1] = pre_table[1 - 1].point_add(&pre_table[10 - 1]); 216 | pre_table[13 - 1] = pre_table[1 - 1].point_add(&pre_table[12 - 1]); 217 | pre_table[15 - 1] = pre_table[1 - 1].point_add(&pre_table[14 - 1]); 218 | 219 | for i in 0..scalar.len() { 220 | for j in 0..(64 / 4) { 221 | let index = scalar[4 - 1 - i] >> ((64 / 4 - 1 - j) * 4); 222 | if index & 0x0f != 0 { 223 | r = pre_table[((index - 1) & 0x0f) as usize].point_add(&r) 224 | } 225 | 226 | if i + 1 == scalar.len() && j + 1 == 64 / 4 { 227 | break; 228 | } 229 | r = r.point_dbl(); 230 | r = r.point_dbl(); 231 | r = r.point_dbl(); 232 | r = r.point_dbl(); 233 | } 234 | } 235 | r 236 | } 237 | 238 | pub fn point_dbl(&self) -> Point { 239 | let x1 = self.x; 240 | let y1 = self.y; 241 | let z1 = self.z; 242 | 243 | let z1_sqr = z1.fp_sqr(); // z1^2 244 | let y1_sqr = y1.fp_sqr(); // y1^2 245 | let alpha_m3 = x1.fp_sub(&z1_sqr).fp_mul(&x1.fp_add(&z1_sqr)).fp_triple(); // 3(x1-delta)*(x1+delta) 246 | let lam6_m4 = x1.fp_mul(&y1_sqr).fp_double().fp_double(); // 4(x1*(y1^2)) 247 | let x3 = alpha_m3.fp_sqr().fp_sub(&lam6_m4.fp_double()); // x3=alpha^2 - 8(x1*(y1^2)) 248 | 249 | let u1 = alpha_m3.fp_mul(&lam6_m4.fp_sub(&x3)); // alpha * (4(x1*(y1^2)) - x3) 250 | let u2 = y1_sqr.fp_sqr().fp_double().fp_double().fp_double(); // 8y1^4 251 | let y3 = u1.fp_sub(&u2); 252 | 253 | let y1_z1 = y1.fp_add(&z1); 254 | let z3 = y1_z1.fp_sqr().fp_sub(&y1_sqr).fp_sub(&z1_sqr); 255 | 256 | Point { 257 | x: x3, 258 | y: y3, 259 | z: z3, 260 | } 261 | } 262 | } 263 | 264 | pub fn g_mul(g: &U256) -> Point { 265 | let mut r = Point::zero(); 266 | let num = 8; 267 | for (index, scalar_word) in g.iter().enumerate() { 268 | for m in 0..num { 269 | let raw_index = ((scalar_word >> (8 * m)) & 0xff) as usize; 270 | if raw_index != 0 { 271 | let a = to_jacobi( 272 | &SM2P256_PRECOMPUTED[num * index + m][raw_index * 2 - 2], 273 | &SM2P256_PRECOMPUTED[num * index + m][raw_index * 2 - 1], 274 | ); 275 | r = r.point_add(&a); 276 | } 277 | } 278 | } 279 | r 280 | } 281 | 282 | pub(crate) fn to_jacobi(x: &U256, y: &U256) -> Point { 283 | let mut r = Point::zero(); 284 | r.x.copy_from_slice(x); 285 | r.y.copy_from_slice(y); 286 | r.z.copy_from_slice(&crate::fields::fp64::SM2_MODP_MONT_ONE); 287 | r 288 | } 289 | 290 | #[cfg(test)] 291 | mod test { 292 | use crate::fields::fp64::fp_to_mont; 293 | use crate::p256_ecc::{g_mul, to_jacobi, Point}; 294 | use crate::u256::u256_from_be_bytes; 295 | 296 | #[test] 297 | fn test_mod_op() { 298 | // Point at Infinity (1:1:0) 299 | let p = Point { 300 | x: u256_from_be_bytes( 301 | &hex::decode("0000000100000000000000000000000000000000ffffffff0000000000000001") 302 | .unwrap(), 303 | ), 304 | y: u256_from_be_bytes( 305 | &hex::decode("0000000100000000000000000000000000000000ffffffff0000000000000001") 306 | .unwrap(), 307 | ), 308 | z: u256_from_be_bytes( 309 | &hex::decode("0000000000000000000000000000000000000000000000000000000000000000") 310 | .unwrap(), 311 | ), 312 | }; 313 | println!("is_valid = {}", p.is_valid()); 314 | println!("is_valid_affine_point = {}", p.is_valid_affine_point()); 315 | println!(); 316 | 317 | // Affine Point [1]G with Montgomery Coordinates 318 | let p = Point { 319 | x: u256_from_be_bytes( 320 | &hex::decode("91167a5ee1c13b05d6a1ed99ac24c3c33e7981eddca6c05061328990f418029e") 321 | .unwrap(), 322 | ), 323 | y: u256_from_be_bytes( 324 | &hex::decode("63cd65d481d735bd8d4cfb066e2a48f8c1f5e5788d3295fac1354e593c2d0ddd") 325 | .unwrap(), 326 | ), 327 | z: u256_from_be_bytes( 328 | &hex::decode("0000000100000000000000000000000000000000ffffffff0000000000000001") 329 | .unwrap(), 330 | ), 331 | }; 332 | println!("is_valid = {}", p.is_valid()); 333 | println!("is_valid_affine_point = {}", p.is_valid_affine_point()); 334 | println!(); 335 | 336 | // Jacobian Point [2]G with Montgomery Coordinates 337 | let p = Point { 338 | x: u256_from_be_bytes( 339 | &hex::decode("398874c476a3b1f77aef3e862601440903243d78d5b614a62eda8381e63c48d6") 340 | .unwrap(), 341 | ), 342 | y: u256_from_be_bytes( 343 | &hex::decode("1fbbdfdddaf4fd475a86a7ae64921d4829f04a88f6cf4dc128385681c1a73e40") 344 | .unwrap(), 345 | ), 346 | z: u256_from_be_bytes( 347 | &hex::decode("c79acba903ae6b7b1a99f60cdc5491f183ebcaf11a652bf5826a9cb2785a1bba") 348 | .unwrap(), 349 | ), 350 | }; 351 | 352 | println!("is_valid = {}", p.is_valid()); 353 | println!( 354 | "is_valid_affine_point = {}", 355 | p.to_affine_point().is_valid_affine_point() 356 | ); 357 | println!(); 358 | 359 | let scalar: &[u64; 4] = &[ 360 | 0xfffff8950000053b, 361 | 0xfffffdc600000543, 362 | 0xfffffb8c00000324, 363 | 0xfffffc4d0000064e, 364 | ]; 365 | 366 | let p = g_mul(&scalar); 367 | println!("is_valid = {}", p.is_valid()); 368 | println!( 369 | "is_valid_affine_point = {}", 370 | p.to_affine_point().is_valid_affine_point() 371 | ); 372 | println!(); 373 | 374 | let scalar: &[u64; 4] = &[ 375 | 0xd89cdf6229c4bddf, 376 | 0xacf005cd78843090, 377 | 0xe5a220abf7212ed6, 378 | 0xdc30061d04874834, 379 | ]; 380 | 381 | let g_x: &[u64; 4] = &[ 382 | 0x715a4589334c74c7, 383 | 0x8fe30bbff2660be1, 384 | 0x5f9904466a39c994, 385 | 0x32c4ae2c1f198119, 386 | ]; 387 | let g_y: &[u64; 4] = &[ 388 | 0x02df32e52139f0a0, 389 | 0xd0a9877cc62a4740, 390 | 0x59bdcee36b692153, 391 | 0xbc3736a2f4f6779c, 392 | ]; 393 | let mont_g_x = fp_to_mont(&g_x); 394 | let mont_g_y = fp_to_mont(&g_y); 395 | let pro_mont_point_g = to_jacobi(&mont_g_x, &mont_g_y); 396 | 397 | let r = pro_mont_point_g.scalar_mul(scalar); 398 | println!("is_valid = {}", r.is_valid()); 399 | println!( 400 | "is_valid_affine_point = {}", 401 | r.to_affine_point().is_valid_affine_point() 402 | ); 403 | } 404 | } 405 | -------------------------------------------------------------------------------- /gm-sm4/src/lib.rs: -------------------------------------------------------------------------------- 1 | 2 | #![doc = include_str!("../README.md")] 3 | 4 | use std::error; 5 | use std::fmt::{Display, Formatter}; 6 | use const_oid::ObjectIdentifier; 7 | 8 | 9 | pub const OID_SM4: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.156.10197.1.104"); 10 | 11 | static SBOX: [u8; 256] = [ 12 | 0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05, 13 | 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 14 | 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62, 15 | 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6, 16 | 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8, 17 | 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35, 18 | 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87, 19 | 0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e, 20 | 0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1, 21 | 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3, 22 | 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f, 23 | 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51, 24 | 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8, 25 | 0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0, 26 | 0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84, 27 | 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48, 28 | ]; 29 | 30 | static FK: [u32; 4] = [0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc]; 31 | 32 | static CK: [u32; 32] = [ 33 | 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, 34 | 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9, 35 | 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229, 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, 36 | 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279, 37 | ]; 38 | 39 | pub type Sm4Result = Result; 40 | 41 | pub enum Sm4Error { 42 | ErrorBlockSize, 43 | ErrorDataLen, 44 | InvalidLastU8, 45 | } 46 | 47 | impl ::std::fmt::Debug for Sm4Error { 48 | fn fmt(&self, f: &mut Formatter<'_>) -> ::std::fmt::Result { 49 | write!(f, "{}", self) 50 | } 51 | } 52 | 53 | impl From for &str { 54 | fn from(e: Sm4Error) -> Self { 55 | match e { 56 | Sm4Error::ErrorBlockSize => "the block size of SM4 must be 16", 57 | Sm4Error::ErrorDataLen => "the data len of SM4 must be 16", 58 | Sm4Error::InvalidLastU8 => { 59 | "the last u8 of cbc_decrypt out in SM4 must be positive which isn't greater than 16" 60 | } 61 | } 62 | } 63 | } 64 | 65 | impl error::Error for Sm4Error {} 66 | 67 | impl Display for Sm4Error { 68 | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { 69 | write!( 70 | f, 71 | "{}", 72 | match self { 73 | Sm4Error::ErrorBlockSize => "the block size of SM4 must be 16", 74 | Sm4Error::ErrorDataLen => "the data len of SM4 must be 16", 75 | Sm4Error::InvalidLastU8 => { 76 | "the last u8 of cbc_decrypt out in SM4 must be positive which isn't greater than 16" 77 | } 78 | } 79 | ) 80 | } 81 | } 82 | 83 | /// (b0 , b1 , b2 , b3 ) = τ( A) = ( Sbox ( a0 ), Sbox ( a1 ), Sbox ( a2 ), Sbox ( a3 ) ) 84 | #[inline] 85 | fn tau(a: u32) -> u32 { 86 | let mut buf = a.to_be_bytes(); 87 | buf[0] = SBOX[buf[0] as usize]; 88 | buf[1] = SBOX[buf[1] as usize]; 89 | buf[2] = SBOX[buf[2] as usize]; 90 | buf[3] = SBOX[buf[3] as usize]; 91 | u32::from_be_bytes(buf) 92 | } 93 | 94 | /// L: linear transformation 95 | /// C = L(B) = B ⊕ (B <<< 2) ⊕ (B <<< 10) ⊕ (B <<< 18) ⊕ (B <<< 24) 96 | #[inline] 97 | fn el(b: u32) -> u32 { 98 | b ^ b.rotate_left(2) ^ b.rotate_left(10) ^ b.rotate_left(18) ^ b.rotate_left(24) 99 | } 100 | 101 | #[inline] 102 | fn el_prime(b: u32) -> u32 { 103 | b ^ b.rotate_left(13) ^ b.rotate_left(23) 104 | } 105 | 106 | #[inline] 107 | fn t(val: u32) -> u32 { 108 | el(tau(val)) 109 | } 110 | 111 | #[inline] 112 | fn t_prime(val: u32) -> u32 { 113 | el_prime(tau(val)) 114 | } 115 | 116 | 117 | /// SM4 block cipher. 118 | /// # Example 119 | /// ```rust 120 | /// fn main() { 121 | /// use hex_literal::hex; 122 | /// use gm_sm4::Sm4Cipher; 123 | /// let key = hex!("0123456789abcdeffedcba9876543210"); 124 | /// let plaintext = key.clone(); 125 | /// let ciphertext = hex!("681edf34d206965e86b3e94f536e4246"); 126 | /// let cipher = Sm4Cipher::new(&key).unwrap(); 127 | /// let enc = cipher.encrypt(&plaintext).unwrap(); 128 | /// assert_eq!(&ciphertext, enc.as_slice()); 129 | /// } 130 | /// ``` 131 | #[derive(Debug, Clone, Eq, PartialEq)] 132 | pub struct Sm4Cipher { 133 | rk: [u32; 32], 134 | } 135 | 136 | impl Sm4Cipher { 137 | pub fn new(k: &[u8]) -> Sm4Result { 138 | let mut rk = [0u32; 32]; 139 | let mk = [ 140 | u32::from_be_bytes(k[0..4].try_into().unwrap()), 141 | u32::from_be_bytes(k[4..8].try_into().unwrap()), 142 | u32::from_be_bytes(k[8..12].try_into().unwrap()), 143 | u32::from_be_bytes(k[12..16].try_into().unwrap()), 144 | ]; 145 | let mut k = [mk[0] ^ FK[0], mk[1] ^ FK[1], mk[2] ^ FK[2], mk[3] ^ FK[3]]; 146 | 147 | for i in 0..8 { 148 | k[0] ^= t_prime(k[1] ^ k[2] ^ k[3] ^ CK[i * 4]); 149 | k[1] ^= t_prime(k[2] ^ k[3] ^ k[0] ^ CK[i * 4 + 1]); 150 | k[2] ^= t_prime(k[3] ^ k[0] ^ k[1] ^ CK[i * 4 + 2]); 151 | k[3] ^= t_prime(k[0] ^ k[1] ^ k[2] ^ CK[i * 4 + 3]); 152 | 153 | rk[i * 4] = k[0]; 154 | rk[i * 4 + 1] = k[1]; 155 | rk[i * 4 + 2] = k[2]; 156 | rk[i * 4 + 3] = k[3]; 157 | } 158 | Ok(Sm4Cipher { rk }) 159 | } 160 | 161 | pub fn encrypt(&self, block: &[u8]) -> Sm4Result> { 162 | let mut x = [ 163 | u32::from_be_bytes(block[0..4].try_into().unwrap()), 164 | u32::from_be_bytes(block[4..8].try_into().unwrap()), 165 | u32::from_be_bytes(block[8..12].try_into().unwrap()), 166 | u32::from_be_bytes(block[12..16].try_into().unwrap()), 167 | ]; 168 | 169 | let rk = &self.rk; 170 | for i in 0..8 { 171 | x[0] ^= t(x[1] ^ x[2] ^ x[3] ^ rk[i * 4]); 172 | x[1] ^= t(x[2] ^ x[3] ^ x[0] ^ rk[i * 4 + 1]); 173 | x[2] ^= t(x[3] ^ x[0] ^ x[1] ^ rk[i * 4 + 2]); 174 | x[3] ^= t(x[0] ^ x[1] ^ x[2] ^ rk[i * 4 + 3]); 175 | } 176 | 177 | let mut out: [u8; 16] = [0; 16]; 178 | out[0..4].copy_from_slice(&x[3].to_be_bytes()); 179 | out[4..8].copy_from_slice(&x[2].to_be_bytes()); 180 | out[8..12].copy_from_slice(&x[1].to_be_bytes()); 181 | out[12..16].copy_from_slice(&x[0].to_be_bytes()); 182 | 183 | Ok(out.to_vec()) 184 | } 185 | 186 | pub fn decrypt(&self, block: &[u8]) -> Sm4Result> { 187 | let mut x = [ 188 | u32::from_be_bytes(block[0..4].try_into().unwrap()), 189 | u32::from_be_bytes(block[4..8].try_into().unwrap()), 190 | u32::from_be_bytes(block[8..12].try_into().unwrap()), 191 | u32::from_be_bytes(block[12..16].try_into().unwrap()), 192 | ]; 193 | let rk = &self.rk; 194 | for i in 0..8 { 195 | x[0] ^= t(x[1] ^ x[2] ^ x[3] ^ rk[31 - i * 4]); 196 | x[1] ^= t(x[2] ^ x[3] ^ x[0] ^ rk[31 - (i * 4 + 1)]); 197 | x[2] ^= t(x[3] ^ x[0] ^ x[1] ^ rk[31 - (i * 4 + 2)]); 198 | x[3] ^= t(x[0] ^ x[1] ^ x[2] ^ rk[31 - (i * 4 + 3)]); 199 | } 200 | let mut out: [u8; 16] = [0; 16]; 201 | out[0..4].copy_from_slice(&x[3].to_be_bytes()); 202 | out[4..8].copy_from_slice(&x[2].to_be_bytes()); 203 | out[8..12].copy_from_slice(&x[1].to_be_bytes()); 204 | out[12..16].copy_from_slice(&x[0].to_be_bytes()); 205 | Ok(out.to_vec()) 206 | } 207 | } 208 | 209 | pub enum CipherMode { 210 | Cfb, 211 | Ofb, 212 | Ctr, 213 | Cbc, 214 | } 215 | 216 | pub struct Sm4CipherMode { 217 | cipher: Sm4Cipher, 218 | mode: CipherMode, 219 | } 220 | 221 | fn block_xor(a: &[u8], b: &[u8]) -> [u8; 16] { 222 | let mut out: [u8; 16] = [0; 16]; 223 | for i in 0..16 { 224 | out[i] = a[i] ^ b[i]; 225 | } 226 | out 227 | } 228 | 229 | fn block_add_one(a: &mut [u8]) { 230 | let mut carry = 1; 231 | for i in 0..16 { 232 | let (t, c) = a[15 - i].overflowing_add(carry); 233 | a[15 - i] = t; 234 | if !c { 235 | return; 236 | } 237 | carry = c as u8; 238 | } 239 | } 240 | 241 | impl Sm4CipherMode { 242 | pub fn new(key: &[u8], mode: CipherMode) -> Sm4Result { 243 | let cipher = Sm4Cipher::new(key)?; 244 | Ok(Sm4CipherMode { cipher, mode }) 245 | } 246 | 247 | pub fn encrypt(&self, data: &[u8], iv: &[u8]) -> Sm4Result> { 248 | if iv.len() != 16 { 249 | return Err(Sm4Error::ErrorBlockSize); 250 | } 251 | match self.mode { 252 | CipherMode::Cfb => self.cfb_encrypt(data, iv), 253 | CipherMode::Ofb => self.ofb_encrypt(data, iv), 254 | CipherMode::Ctr => self.ctr_encrypt(data, iv), 255 | CipherMode::Cbc => self.cbc_encrypt(data, iv), 256 | } 257 | } 258 | 259 | pub fn decrypt(&self, data: &[u8], iv: &[u8]) -> Sm4Result> { 260 | if iv.len() != 16 { 261 | return Err(Sm4Error::ErrorBlockSize); 262 | } 263 | match self.mode { 264 | CipherMode::Cfb => self.cfb_decrypt(data, iv), 265 | CipherMode::Ofb => self.ofb_encrypt(data, iv), 266 | CipherMode::Ctr => self.ctr_encrypt(data, iv), 267 | CipherMode::Cbc => self.cbc_decrypt(data, iv), 268 | } 269 | } 270 | 271 | fn cfb_encrypt(&self, data: &[u8], iv: &[u8]) -> Result, Sm4Error> { 272 | let block_num = data.len() / 16; 273 | let tail_len = data.len() - block_num * 16; 274 | 275 | let mut out: Vec = Vec::new(); 276 | let mut vec_buf: Vec = vec![0; 16]; 277 | vec_buf.clone_from_slice(iv); 278 | 279 | // Normal 280 | for i in 0..block_num { 281 | let enc = self.cipher.encrypt(&vec_buf[..])?; 282 | let ct = block_xor(&enc, &data[i * 16..i * 16 + 16]); 283 | for i in ct.iter() { 284 | out.push(*i); 285 | } 286 | vec_buf.clone_from_slice(&ct); 287 | } 288 | 289 | // Last block 290 | let enc = self.cipher.encrypt(&vec_buf[..])?; 291 | for i in 0..tail_len { 292 | let b = data[block_num * 16 + i] ^ enc[i]; 293 | out.push(b); 294 | } 295 | Ok(out) 296 | } 297 | 298 | fn cfb_decrypt(&self, data: &[u8], iv: &[u8]) -> Result, Sm4Error> { 299 | let block_num = data.len() / 16; 300 | let tail_len = data.len() - block_num * 16; 301 | 302 | let mut out: Vec = Vec::new(); 303 | let mut vec_buf: Vec = vec![0; 16]; 304 | vec_buf.clone_from_slice(iv); 305 | 306 | // Normal 307 | for i in 0..block_num { 308 | let enc = self.cipher.encrypt(&vec_buf[..])?; 309 | let ct = &data[i * 16..i * 16 + 16]; 310 | let pt = block_xor(&enc, ct); 311 | for i in pt.iter() { 312 | out.push(*i); 313 | } 314 | vec_buf.clone_from_slice(ct); 315 | } 316 | 317 | // Last block 318 | let enc = self.cipher.encrypt(&vec_buf[..])?; 319 | for i in 0..tail_len { 320 | let b = data[block_num * 16 + i] ^ enc[i]; 321 | out.push(b); 322 | } 323 | Ok(out) 324 | } 325 | 326 | fn ofb_encrypt(&self, data: &[u8], iv: &[u8]) -> Result, Sm4Error> { 327 | let block_num = data.len() / 16; 328 | let tail_len = data.len() - block_num * 16; 329 | 330 | let mut out: Vec = Vec::new(); 331 | let mut vec_buf: Vec = vec![0; 16]; 332 | vec_buf.clone_from_slice(iv); 333 | 334 | // Normal 335 | for i in 0..block_num { 336 | let enc = self.cipher.encrypt(&vec_buf[..])?; 337 | let ct = block_xor(&enc, &data[i * 16..i * 16 + 16]); 338 | for i in ct.iter() { 339 | out.push(*i); 340 | } 341 | vec_buf.clone_from_slice(&enc); 342 | } 343 | 344 | // Last block 345 | let enc = self.cipher.encrypt(&vec_buf[..])?; 346 | for i in 0..tail_len { 347 | let b = data[block_num * 16 + i] ^ enc[i]; 348 | out.push(b); 349 | } 350 | Ok(out) 351 | } 352 | 353 | fn ctr_encrypt(&self, data: &[u8], iv: &[u8]) -> Result, Sm4Error> { 354 | let block_num = data.len() / 16; 355 | let tail_len = data.len() - block_num * 16; 356 | 357 | let mut out: Vec = Vec::new(); 358 | let mut vec_buf: Vec = vec![0; 16]; 359 | vec_buf.clone_from_slice(iv); 360 | 361 | // Normal 362 | for i in 0..block_num { 363 | let enc = self.cipher.encrypt(&vec_buf[..])?; 364 | let ct = block_xor(&enc, &data[i * 16..i * 16 + 16]); 365 | for i in ct.iter() { 366 | out.push(*i); 367 | } 368 | block_add_one(&mut vec_buf[..]); 369 | } 370 | 371 | // Last block 372 | let enc = self.cipher.encrypt(&vec_buf[..])?; 373 | for i in 0..tail_len { 374 | let b = data[block_num * 16 + i] ^ enc[i]; 375 | out.push(b); 376 | } 377 | Ok(out) 378 | } 379 | 380 | fn cbc_encrypt(&self, data: &[u8], iv: &[u8]) -> Result, Sm4Error> { 381 | let block_num = data.len() / 16; 382 | let remind = data.len() % 16; 383 | 384 | let mut out: Vec = Vec::new(); 385 | let mut vec_buf: Vec = vec![0; 16]; 386 | vec_buf.copy_from_slice(iv); 387 | 388 | // Normal 389 | for i in 0..block_num { 390 | let ct = block_xor(&vec_buf, &data[i * 16..i * 16 + 16]); 391 | let enc = self.cipher.encrypt(&ct)?; 392 | 393 | out.extend_from_slice(&enc); 394 | vec_buf = enc; 395 | } 396 | 397 | if remind != 0 { 398 | let mut last_block = [16 - remind as u8; 16]; 399 | last_block[..remind].copy_from_slice(&data[block_num * 16..]); 400 | 401 | let ct = block_xor(&vec_buf, &last_block); 402 | let enc = self.cipher.encrypt(&ct)?; 403 | out.extend_from_slice(&enc); 404 | } else { 405 | let ff_padding = block_xor(&vec_buf, &[0x10; 16]); 406 | let enc = self.cipher.encrypt(&ff_padding)?; 407 | out.extend_from_slice(&enc); 408 | } 409 | 410 | Ok(out) 411 | } 412 | 413 | fn cbc_decrypt(&self, data: &[u8], iv: &[u8]) -> Result, Sm4Error> { 414 | let data_len = data.len(); 415 | let block_num = data_len / 16; 416 | if data_len % 16 != 0 { 417 | return Err(Sm4Error::ErrorDataLen); 418 | } 419 | 420 | let mut out: Vec = Vec::new(); 421 | let mut vec_buf = [0; 16]; 422 | vec_buf.copy_from_slice(iv); 423 | 424 | // Normal 425 | for i in 0..block_num { 426 | let enc = self.cipher.decrypt(&data[i * 16..i * 16 + 16])?; 427 | let ct = block_xor(&vec_buf, &enc); 428 | 429 | for j in ct.iter() { 430 | out.push(*j); 431 | } 432 | vec_buf.copy_from_slice(&data[i * 16..i * 16 + 16]); 433 | } 434 | 435 | let last_u8 = out[data_len - 1]; 436 | if last_u8 > 0x10 || last_u8 == 0 { 437 | return Err(Sm4Error::InvalidLastU8); 438 | } 439 | out.resize(data_len - last_u8 as usize, 0); 440 | 441 | Ok(out) 442 | } 443 | } 444 | 445 | #[cfg(test)] 446 | mod sm4test { 447 | use hex_literal::hex; 448 | use crate::Sm4Cipher; 449 | 450 | #[test] 451 | fn test_en_1() { 452 | let key = hex!("0123456789abcdeffedcba9876543210"); 453 | let plaintext = key.clone(); 454 | let ciphertext = hex!("681edf34d206965e86b3e94f536e4246"); 455 | 456 | let cipher = Sm4Cipher::new(&key).unwrap(); 457 | 458 | let enc = cipher.encrypt(&plaintext).unwrap(); 459 | assert_eq!(&ciphertext, enc.as_slice()); 460 | } 461 | 462 | #[test] 463 | fn test_en_2() { 464 | let key = hex!("0123456789abcdeffedcba9876543210"); 465 | let plaintext = key.clone(); 466 | let ciphertext = hex!("595298c7c6fd271f0402f804c33d3f66"); 467 | 468 | let cipher = Sm4Cipher::new(&key).unwrap(); 469 | 470 | let mut block = plaintext.to_vec(); 471 | for _ in 0..1_000_000 { 472 | block = cipher.encrypt(&block.as_slice()).unwrap(); 473 | } 474 | assert_eq!(&ciphertext, block.as_slice()); 475 | } 476 | } 477 | --------------------------------------------------------------------------------