001package top.cenze.utils.crypt.sm.sm2; 002 003import org.bouncycastle.crypto.AsymmetricCipherKeyPair; 004import org.bouncycastle.crypto.digests.SM3Digest; 005import org.bouncycastle.crypto.params.ECPrivateKeyParameters; 006import org.bouncycastle.crypto.params.ECPublicKeyParameters; 007import org.bouncycastle.math.ec.ECPoint; 008import top.cenze.utils.ConvertUtil; 009 010import java.math.BigInteger; 011 012public class Cipher { 013 private int ct; 014 private ECPoint p2; 015 private SM3Digest sm3keybase; 016 private SM3Digest sm3c3; 017 private byte key[]; 018 private byte keyOff; 019 020 public Cipher() 021 { 022 this.ct = 1; 023 this.key = new byte[32]; 024 this.keyOff = 0; 025 } 026 027 private void Reset() 028 { 029 this.sm3keybase = new SM3Digest(); 030 this.sm3c3 = new SM3Digest(); 031 032 byte p[] = ConvertUtil.byteConvert32Bytes(p2.getX().toBigInteger()); 033 this.sm3keybase.update(p, 0, p.length); 034 this.sm3c3.update(p, 0, p.length); 035 036 p = ConvertUtil.byteConvert32Bytes(p2.getY().toBigInteger()); 037 this.sm3keybase.update(p, 0, p.length); 038 this.ct = 1; 039 NextKey(); 040 } 041 042 private void NextKey() 043 { 044 SM3Digest sm3keycur = new SM3Digest(this.sm3keybase); 045 sm3keycur.update((byte) (ct >> 24 & 0xff)); 046 sm3keycur.update((byte) (ct >> 16 & 0xff)); 047 sm3keycur.update((byte) (ct >> 8 & 0xff)); 048 sm3keycur.update((byte) (ct & 0xff)); 049 sm3keycur.doFinal(key, 0); 050 this.keyOff = 0; 051 this.ct++; 052 } 053 054 public ECPoint Init_enc(SM2 sm2, ECPoint userKey) 055 { 056 AsymmetricCipherKeyPair key = sm2.ecc_key_pair_generator.generateKeyPair(); 057 ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters) key.getPrivate(); 058 ECPublicKeyParameters ecpub = (ECPublicKeyParameters) key.getPublic(); 059 BigInteger k = ecpriv.getD(); 060 ECPoint c1 = ecpub.getQ(); 061 this.p2 = userKey.multiply(k); 062 Reset(); 063 return c1; 064 } 065 066 public void Encrypt(byte data[]) 067 { 068 this.sm3c3.update(data, 0, data.length); 069 for (int i = 0; i < data.length; i++) 070 { 071 if (keyOff == key.length) 072 { 073 NextKey(); 074 } 075 data[i] ^= key[keyOff++]; 076 } 077 } 078 079 public void Init_dec(BigInteger userD, ECPoint c1) 080 { 081 this.p2 = c1.multiply(userD); 082 Reset(); 083 } 084 085 public void Decrypt(byte data[]) 086 { 087 for (int i = 0; i < data.length; i++) 088 { 089 if (keyOff == key.length) 090 { 091 NextKey(); 092 } 093 data[i] ^= key[keyOff++]; 094 } 095 096 this.sm3c3.update(data, 0, data.length); 097 } 098 099 public void Dofinal(byte c3[]) 100 { 101 byte p[] = ConvertUtil.byteConvert32Bytes(p2.getY().toBigInteger()); 102 this.sm3c3.update(p, 0, p.length); 103 this.sm3c3.doFinal(c3, 0); 104 Reset(); 105 } 106}