_G='Data length error!' _F='%08x' _E='utf8' _D='%%0%dx' _C=None _B='utf-8' _A='p' import random,urllib.parse,base64,binascii from math import ceil import copy def str_to_bytes(input_str): A=[] for B in input_str: C=urllib.parse.quote(B) if len(C)==1:A.append(ord(B)) else: for D in C.split('%')[1:]:A.append(int('0x'+D,16)) return A def bytes_to_hex(bytes_input): B='' for C in bytes_input: A=hex(C)[2:] if len(A)==1:A='0'+A B+=A return B def string_to_hex(s):return''if s==''else bytes_to_hex(str_to_bytes(s)) def d(data,publicKey):A=data;A=string_to_hex(A).encode();B=BB(public_key=publicKey,mode=1);C=B.encrypt(A);return'04'+C.hex() def e(e=_C,c=_C,n=_C): D='0123456789';A=list(D) if n==1:A=list(D) else:A=list('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') B=[] if c is _C:c=len(A) if e: for E in range(e):B.append(A[int(random.random()*c)]) else: for C in range(36): if C in[8,13,18,23]:B.append('-') elif C==14:B.append('4') else: e=int(random.random()*16) if C==19:B.append(A[3&e|8]) else:B.append(A[e]) return''.join(B) def a(data,key):B=data;A=key;B=B.encode(_B);A=A.encode(_B);C=AA(padding_mode=3);C.set_key(A,SM4_ENCRYPT);D=C.crypt_cbc(A[0:8]+A[-8:],B);E=base64.b64encode(D);return E.decode() def b(data,key):B=data;A=key;B=B.encode(_B);A=A.encode(_B);D=base64.b64decode(B);C=AA(padding_mode=3);C.set_key(A,SM4_DECRYPT);E=C.crypt_cbc(A[0:8]+A[-8:],D);return E.decode() def c(data):A=data;A=A.encode(_B);A=bytes_to_list(A);return m_hash(A) xor=lambda a,b:list(map(lambda x,y:x^y,a,b)) rotl=lambda x,n:x<>32-n&4294967295 get_uint32_be=lambda key_data:key_data[0]<<24|key_data[1]<<16|key_data[2]<<8|key_data[3] put_uint32_be=lambda n:[n>>24&255,n>>16&255,n>>8&255,n&255] pkcs7_padding=lambda data,block=16:data+[16-len(data)%block for A in range(16-len(data)%block)] zero_padding=lambda data,block=16:data+[0 for A in range(16-len(data)%block)] pkcs7_unpadding=lambda data:data[:-data[-1]] zero_unpadding=lambda data,i=1:data[:-i]if data[-i]==0 else i+1 list_to_bytes=lambda data:b''.join([bytes((A,))for A in data]) bytes_to_list=lambda data:[A for A in data] random_hex=lambda x:''.join([random.choice('0123456789abcdef')for A in range(x)]) def pboc_padding(data,block=16): B=block;A=data;A=A.hex().upper();B=B*2 if len(A)%B!=0:A=A+'80' while len(A)%B!=0:A=A+'00' return bytes_to_list(bytes.fromhex(A)) def iso9797m2_padding(data,block=16): B=block;A=data;A=A.hex().upper();B=B*2;A=A+'80' while len(A)%B!=0:A=A+'00' return bytes_to_list(bytes.fromhex(A)) def pboc_unpadding(data): A=data if len(A)<16:raise Exception(_G) if len(A)==16:0 else: while A[-1:]!=[128]:A.pop() A.pop() return A def iso9797m2_unpadding(data): A=data if len(A)<=16:raise Exception(_G) while A[-1:]!=[128]:A.pop() A.pop();return A default_ecc_table={'n':'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123',_A:'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF','g':'32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0','a':'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC','b':'28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93'} class BB: def __init__(A,public_key,ecc_table=default_ecc_table,mode=1,asn1=False):'\n mode: 0-C1C2C3, 1-C1C3C2 (default is 1)\n ';C=ecc_table;B=public_key;A.public_key=B[2:]if B.startswith('04')and len(B)==130 else B;A.para_len=len(C['n']);A.ecc_a3=(int(C['a'],base=16)+3)%int(C[_A],base=16);A.ecc_table=C;assert mode in(0,1),'mode must be one of (0, 1)';A.mode=mode;A.asn1=asn1 def _kg(B,k,Point): C=Point;C='%s%s'%(C,'1');E='8' for G in range(B.para_len-1):E+='0' F=int(E,16);A=C;D=False for H in range(B.para_len*4): if D:A=B._double_point(A) if k&F!=0: if D:A=B._add_point(A,C) else:D=True;A=C k=k<<1 return B._convert_jacb_to_nor(A) def _double_point(A,Point): G=Point;N=len(G);J=2*A.para_len if N>1)-D)%int(A.ecc_table[_A],base=16) else:E=(F+(F>>1)-D)%int(A.ecc_table[_A],base=16) B=B*E%int(A.ecc_table[_A],base=16);Q=(B-I)%int(A.ecc_table[_A],base=16);M=_D%A.para_len;M=M*3;return M%(P,Q,O) def _add_point(A,P1,P2): E=2*A.para_len;J=len(P1);M=len(P2) if JD:D=D+64 for A in range(C,D):B.append(0) E=H*8;I=[E%256] for A in range(7):E=int(E/256);I.append(E%256) for A in range(8):B.append(I[7-A]) J=round(len(B)/64);K=[] for A in range(0,J):K.append(B[A*64:(A+1)*64]) F=[];F.append(IV) for A in range(0,J):F.append(m_cf(F[A],K[A])) L=F[A+1];G='' for A in L:G='%s%08x'%(G,A) return G def m_kdf(z,klen): A=klen;A=int(A);C=1;D=ceil(A/32);E=[A for A in bytes.fromhex(z.decode(_E))];B='' for G in range(D):F=E+[A for A in binascii.a2b_hex((_F%C).encode(_E))];B=B+m_hash(F);C+=1 return B[0:A*2] SM4_BOXES_TABLE=[214,144,233,254,204,225,61,183,22,182,20,194,40,251,44,5,43,103,154,118,42,190,4,195,170,68,19,38,73,134,6,153,156,66,80,244,145,239,152,122,51,84,11,67,237,207,172,98,228,179,28,169,201,8,232,149,128,223,148,250,117,143,63,166,71,7,167,252,243,115,23,186,131,89,60,25,230,133,79,168,104,107,129,178,113,100,218,139,248,235,15,75,112,86,157,53,30,36,14,94,99,88,209,162,37,34,124,59,1,33,120,135,212,0,70,87,159,211,39,82,76,54,2,231,160,196,200,158,234,191,138,210,64,199,56,181,163,247,242,206,249,97,21,161,224,174,93,164,155,52,26,85,173,147,50,48,245,140,177,227,29,246,226,46,130,102,202,96,192,41,35,171,13,83,78,111,213,219,55,69,222,253,142,47,3,255,106,114,109,108,91,81,141,27,175,146,187,221,188,127,17,217,92,65,31,16,90,216,10,193,49,136,165,205,123,189,45,116,208,18,184,229,180,176,137,105,151,74,12,150,119,126,101,185,241,9,197,110,198,132,24,240,125,236,58,220,77,32,121,238,95,62,215,203,57,72] SM4_FK=[2746333894,1453994832,1736282519,2993693404] SM4_CK=[462357,472066609,943670861,1415275113,1886879365,2358483617,2830087869,3301692121,3773296373,4228057617,404694573,876298825,1347903077,1819507329,2291111581,2762715833,3234320085,3705924337,4177462797,337322537,808926789,1280531041,1752135293,2223739545,2695343797,3166948049,3638552301,4110090761,269950501,741554753,1213159005,1684763257] SM4_ENCRYPT=0 SM4_DECRYPT=1 NoPadding=0 ZERO=1 ISO9797M2=2 PKCS7=3 PBOC=4 class AA: def __init__(A,mode=SM4_ENCRYPT,padding_mode=PKCS7):A.sk=[0]*32;A.mode=mode;A.padding_mode=padding_mode @classmethod def _round_key(E,ka):A=[0,0,0,0];B=put_uint32_be(ka);A[0]=SM4_BOXES_TABLE[B[0]];A[1]=SM4_BOXES_TABLE[B[1]];A[2]=SM4_BOXES_TABLE[B[2]];A[3]=SM4_BOXES_TABLE[B[3]];C=get_uint32_be(A[0:4]);D=C^rotl(C,13)^rotl(C,23);return D @classmethod def _f(B,x0,x1,x2,x3,rk): def A(ka):A=[0,0,0,0];C=put_uint32_be(ka);A[0]=SM4_BOXES_TABLE[C[0]];A[1]=SM4_BOXES_TABLE[C[1]];A[2]=SM4_BOXES_TABLE[C[2]];A[3]=SM4_BOXES_TABLE[C[3]];B=get_uint32_be(A[0:4]);D=B^rotl(B,2)^rotl(B,10)^rotl(B,18)^rotl(B,24);return D return x0^A(x1^x2^x3^rk) def set_key(B,key,mode): D=key;D=bytes_to_list(D);E=[0,0,0,0];C=[0]*36;E[0]=get_uint32_be(D[0:4]);E[1]=get_uint32_be(D[4:8]);E[2]=get_uint32_be(D[8:12]);E[3]=get_uint32_be(D[12:16]);C[0:4]=xor(E[0:4],SM4_FK[0:4]) for A in range(32):C[A+4]=C[A]^B._round_key(C[A+1]^C[A+2]^C[A+3]^SM4_CK[A]);B.sk[A]=C[A+4] B.mode=mode if mode==SM4_DECRYPT: for F in range(16):G=B.sk[F];B.sk[F]=B.sk[31-F];B.sk[31-F]=G def one_round(E,sk,in_put): D=in_put;C=[];A=[0]*36;A[0]=get_uint32_be(D[0:4]);A[1]=get_uint32_be(D[4:8]);A[2]=get_uint32_be(D[8:12]);A[3]=get_uint32_be(D[12:16]) for B in range(32):A[B+4]=E._f(A[B],A[B+1],A[B+2],A[B+3],sk[B]) C+=put_uint32_be(A[35]);C+=put_uint32_be(A[34]);C+=put_uint32_be(A[33]);C+=put_uint32_be(A[32]);return C def crypt_ecb(A,input_data): B=input_data if A.mode==SM4_ENCRYPT: if A.padding_mode==NoPadding:0 if A.padding_mode==ZERO:B=zero_padding(bytes_to_list(B)) if A.padding_mode==ISO9797M2:B=iso9797m2_padding(B) if A.padding_mode==PKCS7:B=pkcs7_padding(bytes_to_list(B)) if A.padding_mode==PBOC:B=pboc_padding(B) E=len(B);D=0;C=[] while E>0:C+=A.one_round(A.sk,B[D:D+16]);D+=16;E-=16 if A.mode==SM4_DECRYPT: if A.padding_mode==NoPadding:0 if A.padding_mode==ZERO:return list_to_bytes(zero_unpadding(C)) if A.padding_mode==ISO9797M2:return list_to_bytes(iso9797m2_unpadding(C)) if A.padding_mode==PKCS7:return list_to_bytes(pkcs7_unpadding(C)) if A.padding_mode==PBOC:return list_to_bytes(pboc_unpadding(C)) return list_to_bytes(C) def crypt_cbc(A,iv,input_data): E=iv;C=input_data;B=0;D=[];G=[0]*16;E=bytes_to_list(E) if A.mode==SM4_ENCRYPT: if A.padding_mode==NoPadding:0 if A.padding_mode==ZERO:C=zero_padding(bytes_to_list(C)) if A.padding_mode==ISO9797M2:C=iso9797m2_padding(C) if A.padding_mode==PKCS7:C=pkcs7_padding(bytes_to_list(C)) if A.padding_mode==PBOC:C=pboc_padding(C) F=len(C) while F>0:G[0:16]=xor(C[B:B+16],E[0:16]);D+=A.one_round(A.sk,G[0:16]);E=copy.deepcopy(D[B:B+16]);B+=16;F-=16 return list_to_bytes(D) else: F=len(C) while F>0:D+=A.one_round(A.sk,C[B:B+16]);D[B:B+16]=xor(D[B:B+16],E[0:16]);E=copy.deepcopy(C[B:B+16]);B+=16;F-=16 if A.padding_mode==NoPadding:0 if A.padding_mode==ZERO:return list_to_bytes(zero_unpadding(D)) if A.padding_mode==ISO9797M2:return list_to_bytes(iso9797m2_unpadding(D)) if A.padding_mode==PKCS7:return list_to_bytes(pkcs7_unpadding(D)) if A.padding_mode==PBOC:return list_to_bytes(pboc_unpadding(D)) return list_to_bytes(D)