crypto: add a crypto.des module (#13065)
							parent
							
								
									7276705684
								
							
						
					
					
						commit
						2b42ea9883
					
				|  | @ -0,0 +1,121 @@ | |||
| // The source code refers to the go standard library, which will be combined with AES in the future.
 | ||||
| 
 | ||||
| // Use of this source code is governed by an MIT license
 | ||||
| // that can be found in the LICENSE file.
 | ||||
| // Cipher block chaining (CBC) mode.
 | ||||
| // CBC provides confidentiality by xoring (chaining) each plaintext block
 | ||||
| // with the previous ciphertext block before applying the block cipher.
 | ||||
| // See NIST SP 800-38A, pp 10-11
 | ||||
| // NOTE this will be moved to crypto.cipher interface (joe-c)
 | ||||
| module cipher | ||||
| 
 | ||||
| import crypto.internal.subtle | ||||
| 
 | ||||
| struct Cbc { | ||||
| mut: | ||||
| 	b          Block | ||||
| 	block_size int | ||||
| 	iv         []byte | ||||
| 	tmp        []byte | ||||
| } | ||||
| 
 | ||||
| // internal
 | ||||
| fn new_des_cbc(b Block, iv []byte) Cbc { | ||||
| 	return Cbc{ | ||||
| 		b: b | ||||
| 		block_size: b.block_size | ||||
| 		iv: iv.clone() | ||||
| 		tmp: []byte{len: b.block_size} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // new_cbc returns a `DesCbc` which encrypts in cipher block chaining
 | ||||
| // mode, using the given Block. The length of iv must be the same as the
 | ||||
| // Block's block size.
 | ||||
| pub fn new_cbc(b Block, iv []byte) Cbc { | ||||
| 	if iv.len != b.block_size { | ||||
| 		panic('crypto.cipher.new_cbc_encrypter: IV length must equal block size') | ||||
| 	} | ||||
| 	return new_des_cbc(b, iv) | ||||
| } | ||||
| 
 | ||||
| // encrypt_blocks encrypts the blocks in `src_` to `dst_`.
 | ||||
| // Please note: `dst_` is mutable for performance reasons.
 | ||||
| pub fn (x &Cbc) encrypt_blocks(mut dst_ []byte, src_ []byte) { | ||||
| 	unsafe { | ||||
| 		mut dst := *dst_ | ||||
| 		mut src := src_ | ||||
| 		if src.len % x.block_size != 0 { | ||||
| 			panic('crypto.cipher: input not full blocks') | ||||
| 		} | ||||
| 		if dst.len < src.len { | ||||
| 			panic('crypto.cipher: output smaller than input') | ||||
| 		} | ||||
| 		if subtle.inexact_overlap(dst[..src.len], src_) { | ||||
| 			panic('crypto.cipher: invalid buffer overlap') | ||||
| 		} | ||||
| 		mut iv := x.iv | ||||
| 		for src.len > 0 { | ||||
| 			// Write the xor to dst, then encrypt in place.
 | ||||
| 			xor_bytes(mut dst[..x.block_size], src[..x.block_size], iv) | ||||
| 			x.b.encrypt(mut dst[..x.block_size], dst[..x.block_size]) | ||||
| 			// Move to the next block with this block as the next iv.
 | ||||
| 			iv = dst[..x.block_size] | ||||
| 			if x.block_size >= src.len { | ||||
| 				src = [] | ||||
| 			} else { | ||||
| 				src = src[x.block_size..] | ||||
| 			} | ||||
| 			dst = dst[x.block_size..] | ||||
| 		} | ||||
| 		// Save the iv for the next crypt_blocks call.
 | ||||
| 		copy(x.iv, iv) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // decrypt_blocks decrypts the blocks in `src` to `dst`.
 | ||||
| // Please note: `dst` is mutable for performance reasons.
 | ||||
| pub fn (mut x Cbc) decrypt_blocks(mut dst []byte, src []byte) { | ||||
| 	if src.len % x.block_size != 0 { | ||||
| 		panic('crypto.cipher: input not full blocks') | ||||
| 	} | ||||
| 	if dst.len < src.len { | ||||
| 		panic('crypto.cipher: output smaller than input') | ||||
| 	} | ||||
| 	if subtle.inexact_overlap((*dst)[..src.len], src) { | ||||
| 		panic('crypto.cipher: invalid buffer overlap') | ||||
| 	} | ||||
| 	if src.len == 0 { | ||||
| 		return | ||||
| 	} | ||||
| 	// For each block, we need to xor the decrypted data with the previous block's ciphertext (the iv).
 | ||||
| 	// To avoid making a copy each time, we loop over the blocks BACKWARDS.
 | ||||
| 	mut end := src.len | ||||
| 	mut start := end - x.block_size | ||||
| 	mut prev := start - x.block_size | ||||
| 	// Copy the last block of ciphertext in preparation as the new iv.
 | ||||
| 	copy(x.tmp, src[start..end]) | ||||
| 	// Loop over all but the first block.
 | ||||
| 	for start > 0 { | ||||
| 		src_chunk := src[start..end] | ||||
| 		x.b.decrypt(mut (*dst)[start..end], src_chunk) | ||||
| 		xor_bytes(mut (*dst)[start..end], (*dst)[start..end], src[prev..start]) | ||||
| 		end = start | ||||
| 		start = prev | ||||
| 		prev -= x.block_size | ||||
| 	} | ||||
| 	// The first block is special because it uses the saved iv.
 | ||||
| 	src_chunk := src[start..end] | ||||
| 	x.b.decrypt(mut (*dst)[start..end], src_chunk) | ||||
| 	xor_bytes(mut (*dst)[start..end], (*dst)[start..end], x.iv) | ||||
| 	// Set the new iv to the first block we copied earlier.
 | ||||
| 	x.iv = x.tmp | ||||
| 	x.tmp = x.iv | ||||
| } | ||||
| 
 | ||||
| fn (x &Cbc) set_iv(iv []byte) { | ||||
| 	if iv.len != x.iv.len { | ||||
| 		panic('cipher: incorrect length IV') | ||||
| 	} | ||||
| 	copy(x.iv, iv) | ||||
| } | ||||
|  | @ -0,0 +1,55 @@ | |||
| // The source code refers to the go standard library, which will be combined with AES in the future.
 | ||||
| 
 | ||||
| module cipher | ||||
| 
 | ||||
| // A Block represents an implementation of block cipher
 | ||||
| // using a given key. It provides the capability to encrypt
 | ||||
| // or decrypt individual blocks. The mode implementations
 | ||||
| // extend that capability to streams of blocks.
 | ||||
| interface Block { | ||||
| 	block_size int // block_size returns the cipher's block size.
 | ||||
| 	encrypt(mut dst []byte, src []byte) // Encrypt encrypts the first block in src into dst.
 | ||||
| 	// Dst and src must overlap entirely or not at all.
 | ||||
| 	decrypt(mut dst []byte, src []byte) // Decrypt decrypts the first block in src into dst.
 | ||||
| 	// Dst and src must overlap entirely or not at all.
 | ||||
| } | ||||
| 
 | ||||
| // A Stream represents a stream cipher.
 | ||||
| interface Stream { | ||||
| 	// xor_key_stream XORs each byte in the given slice with a byte from the
 | ||||
| 	// cipher's key stream. Dst and src must overlap entirely or not at all.
 | ||||
| 	//
 | ||||
| 	// If len(dst) < len(src), xor_key_stream should panic. It is acceptable
 | ||||
| 	// to pass a dst bigger than src, and in that case, xor_key_stream will
 | ||||
| 	// only update dst[:len(src)] and will not touch the rest of dst.
 | ||||
| 	//
 | ||||
| 	// Multiple calls to xor_key_stream behave as if the concatenation of
 | ||||
| 	// the src buffers was passed in a single run. That is, Stream
 | ||||
| 	// maintains state and does not reset at each xor_key_stream call.
 | ||||
| 	xor_key_stream(mut dst []byte, src []byte) | ||||
| } | ||||
| 
 | ||||
| // A BlockMode represents a block cipher running in a block-based mode (CBC,
 | ||||
| // ECB etc).
 | ||||
| interface BlockMode { | ||||
| 	block_size int // block_size returns the mode's block size.
 | ||||
| 	crypt_blocks(mut dst []byte, src []byte) // crypt_blocks encrypts or decrypts a number of blocks. The length of
 | ||||
| 	// src must be a multiple of the block size. Dst and src must overlap
 | ||||
| 	// entirely or not at all.
 | ||||
| 	//
 | ||||
| 	// If len(dst) < len(src), crypt_blocks should panic. It is acceptable
 | ||||
| 	// to pass a dst bigger than src, and in that case, crypt_blocks will
 | ||||
| 	// only update dst[:len(src)] and will not touch the rest of dst.
 | ||||
| 	//
 | ||||
| 	// Multiple calls to crypt_blocks behave as if the concatenation of
 | ||||
| 	// the src buffers was passed in a single run. That is, BlockMode
 | ||||
| 	// maintains state and does not reset at each crypt_blocks call.
 | ||||
| } | ||||
| 
 | ||||
| // Utility routines
 | ||||
| 
 | ||||
| // fn dup(p []byte) []byte {
 | ||||
| // 	q := make([]byte, p.len)
 | ||||
| // 	copy(q, p)
 | ||||
| // 	return q
 | ||||
| // }
 | ||||
|  | @ -0,0 +1,54 @@ | |||
| import crypto.des | ||||
| import crypto.cipher | ||||
| 
 | ||||
| const ( | ||||
| 	key = '123456789012345678901234'.bytes() | ||||
| 	iv  = 'abcdegfh'.bytes() | ||||
| 	str = '73c86d43a9d700a253a96c85b0f6b03ac9792e0e757f869cca306bd3cba1c62b' | ||||
| ) | ||||
| 
 | ||||
| fn test_triple_des_cbc() { | ||||
| 	mut src := str.bytes() | ||||
| 
 | ||||
| 	triple_des_cbc_en(mut src, key, iv) | ||||
| 	assert src.hex() == '59d657007dc96062e8fffd574afda480ddba21fa06337ac5676eb4e40db256f2ab31ed442c0e4a82ef59b96292d24902c86b20c50bd8506e387775ca58f8c4fe' | ||||
| 
 | ||||
| 	triple_des_cbc_de(mut src, key, iv) | ||||
| 	assert src.bytestr() == str | ||||
| 	println('test_triple_des_cbc ok') | ||||
| } | ||||
| 
 | ||||
| fn test_des_cbc() { | ||||
| 	mut src := str.bytes() | ||||
| 
 | ||||
| 	des_cbc_en(mut src, key[..8], iv) | ||||
| 	assert src.hex() == '198f94ca5989900ce73b26c3ce0005fa747b74d81e8cc5d529f96c1a2e7748d39f9900b9049cbfda35ef720d495b134f4f7dd2d7d3d910af488cdccd27d9f057' | ||||
| 
 | ||||
| 	des_cbc_de(mut src, key[..8], iv) | ||||
| 	assert src.bytestr() == str | ||||
| 	println('test_des_cbc ok') | ||||
| } | ||||
| 
 | ||||
| fn des_cbc_en(mut src []byte, key []byte, iv []byte) { | ||||
| 	block := des.new_cipher(key) | ||||
| 	mode := cipher.new_cbc(block, iv) | ||||
| 	mode.encrypt_blocks(mut src, src.clone()) | ||||
| } | ||||
| 
 | ||||
| fn des_cbc_de(mut src []byte, key []byte, iv []byte) { | ||||
| 	block := des.new_cipher(key) | ||||
| 	mut mode := cipher.new_cbc(block, iv) | ||||
| 	mode.decrypt_blocks(mut src, src.clone()) | ||||
| } | ||||
| 
 | ||||
| fn triple_des_cbc_en(mut src []byte, key []byte, iv []byte) { | ||||
| 	block := des.new_triple_des_cipher(key) | ||||
| 	mode := cipher.new_cbc(block, iv) | ||||
| 	mode.encrypt_blocks(mut src, src.clone()) | ||||
| } | ||||
| 
 | ||||
| fn triple_des_cbc_de(mut src []byte, key []byte, iv []byte) { | ||||
| 	block := des.new_triple_des_cipher(key) | ||||
| 	mut mode := cipher.new_cbc(block, iv) | ||||
| 	mode.decrypt_blocks(mut src, src.clone()) | ||||
| } | ||||
|  | @ -0,0 +1,189 @@ | |||
| // The source code refers to the go standard library, which can be merged with AES later
 | ||||
| 
 | ||||
| module des | ||||
| 
 | ||||
| import encoding.binary | ||||
| 
 | ||||
| fn feistel(ll u32, rr u32, k0 u64, k1 u64) (u32, u32) { | ||||
| 	mut l := ll | ||||
| 	mut r := rr | ||||
| 	mut t := r ^ u32(k0 >> 32) | ||||
| 
 | ||||
| 	l ^= feistel_box[7][t & 0x3f] ^ feistel_box[5][(t >> 8) & 0x3f] ^ feistel_box[3][(t >> 16) & 0x3f] ^ feistel_box[1][(t >> 24) & 0x3f] | ||||
| 
 | ||||
| 	t = ((r << 28) | (r >> 4)) ^ u32(k0) | ||||
| 	l ^= feistel_box[6][t & 0x3f] ^ feistel_box[4][(t >> 8) & 0x3f] ^ feistel_box[2][(t >> 16) & 0x3f] ^ feistel_box[0][(t >> 24) & 0x3f] | ||||
| 
 | ||||
| 	t = l ^ u32(k1 >> 32) | ||||
| 	r ^= feistel_box[7][t & 0x3f] ^ feistel_box[5][(t >> 8) & 0x3f] ^ feistel_box[3][(t >> 16) & 0x3f] ^ feistel_box[1][(t >> 24) & 0x3f] | ||||
| 
 | ||||
| 	t = ((l << 28) | (l >> 4)) ^ u32(k1) | ||||
| 	r ^= feistel_box[6][t & 0x3f] ^ feistel_box[4][(t >> 8) & 0x3f] ^ feistel_box[2][(t >> 16) & 0x3f] ^ feistel_box[0][(t >> 24) & 0x3f] | ||||
| 
 | ||||
| 	return l, r | ||||
| } | ||||
| 
 | ||||
| fn crypt_block(subkeys []u64, mut dst []byte, src []byte, decrypt bool) { | ||||
| 	mut b := binary.big_endian_u64(src) | ||||
| 	b = permute_initial_block(b) | ||||
| 
 | ||||
| 	mut left, mut right := u32(b >> 32), u32(b) | ||||
| 
 | ||||
| 	left = (left << 1) | (left >> 31) | ||||
| 	right = (right << 1) | (right >> 31) | ||||
| 
 | ||||
| 	if decrypt { | ||||
| 		for i := 0; i < 8; i++ { | ||||
| 			left, right = feistel(left, right, subkeys[15 - 2 * i], subkeys[15 - (2 * i + 1)]) | ||||
| 		} | ||||
| 	} else { | ||||
| 		for i := 0; i < 8; i++ { | ||||
| 			left, right = feistel(left, right, subkeys[2 * i], subkeys[2 * i + 1]) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	left = (left << 31) | (left >> 1) | ||||
| 	right = (right << 31) | (right >> 1) | ||||
| 
 | ||||
| 	// switch left & right and perform final permutation
 | ||||
| 	pre_output := (u64(right) << 32) | u64(left) | ||||
| 	binary.big_endian_put_u64(mut dst, permute_final_block(pre_output)) | ||||
| } | ||||
| 
 | ||||
| // Encrypt one block from src into dst, using the subkeys.
 | ||||
| pub fn encrypt_block(subkeys []u64, mut dst []byte, src []byte) { | ||||
| 	crypt_block(subkeys, mut dst, src, false) | ||||
| } | ||||
| 
 | ||||
| // Decrypt one block from src into dst, using the subkeys.
 | ||||
| fn decrypt_block(subkeys []u64, mut dst []byte, src []byte) { | ||||
| 	crypt_block(subkeys, mut dst, src, true) | ||||
| } | ||||
| 
 | ||||
| // general purpose function to perform DES block permutations
 | ||||
| fn permute_block(src u64, permutation []byte) u64 { | ||||
| 	mut block := u64(0) | ||||
| 	for position, n in permutation { | ||||
| 		bit := (src >> u64(u8(n))) & 1 | ||||
| 		block |= bit << u64((permutation.len - 1) - position) | ||||
| 	} | ||||
| 	return block | ||||
| } | ||||
| 
 | ||||
| // permuteInitial_block is equivalent to the permutation defined
 | ||||
| // by initialPermutation.
 | ||||
| fn permute_initial_block(b u64) u64 { | ||||
| 	// block = b7 b6 b5 b4 b3 b2 b1 b0 (8 bytes)
 | ||||
| 	mut block := b | ||||
| 	mut b1 := block >> 48 | ||||
| 	mut b2 := block << 48 | ||||
| 	block ^= b1 ^ b2 ^ b1 << 48 ^ b2 >> 48 | ||||
| 
 | ||||
| 	// block = b1 b0 b5 b4 b3 b2 b7 b6
 | ||||
| 	b1 = block >> 32 & 0xff00ff | ||||
| 	b2 = (block & 0xff00ff00) | ||||
| 	block ^= b1 << 32 ^ b2 ^ b1 << 8 ^ b2 << 24 // exchange b0 b4 with b3 b7
 | ||||
| 
 | ||||
| 	// block is now b1 b3 b5 b7 b0 b2 b4 b6, the permutation:
 | ||||
| 	//                  ...  8
 | ||||
| 	//                  ... 24
 | ||||
| 	//                  ... 40
 | ||||
| 	//                  ... 56
 | ||||
| 	//  7  6  5  4  3  2  1  0
 | ||||
| 	// 23 22 21 20 19 18 17 16
 | ||||
| 	//                  ... 32
 | ||||
| 	//                  ... 48
 | ||||
| 
 | ||||
| 	// exchange 4,5,6,7 with 32,33,34,35 etc.
 | ||||
| 	b1 = block & 0x0f0f00000f0f0000 | ||||
| 	b2 = block & 0x0000f0f00000f0f0 | ||||
| 	block ^= b1 ^ b2 ^ b1 >> 12 ^ b2 << 12 | ||||
| 
 | ||||
| 	// block is the permutation:
 | ||||
| 	//
 | ||||
| 	//   [+8]         [+40]
 | ||||
| 	//
 | ||||
| 	//  7  6  5  4
 | ||||
| 	// 23 22 21 20
 | ||||
| 	//  3  2  1  0
 | ||||
| 	// 19 18 17 16    [+32]
 | ||||
| 
 | ||||
| 	// exchange 0,1,4,5 with 18,19,22,23
 | ||||
| 	b1 = block & 0x3300330033003300 | ||||
| 	b2 = block & 0x00cc00cc00cc00cc | ||||
| 	block ^= b1 ^ b2 ^ b1 >> 6 ^ b2 << 6 | ||||
| 
 | ||||
| 	// block is the permutation:
 | ||||
| 	// 15 14
 | ||||
| 	// 13 12
 | ||||
| 	// 11 10
 | ||||
| 	//  9  8
 | ||||
| 	//  7  6
 | ||||
| 	//  5  4
 | ||||
| 	//  3  2
 | ||||
| 	//  1  0 [+16] [+32] [+64]
 | ||||
| 
 | ||||
| 	// exchange 0,2,4,6 with 9,11,13,15:
 | ||||
| 	b1 = block & 0xaaaaaaaa55555555 | ||||
| 	block ^= b1 ^ b1 >> 33 ^ b1 << 33 | ||||
| 
 | ||||
| 	// block is the permutation:
 | ||||
| 	// 6 14 22 30 38 46 54 62
 | ||||
| 	// 4 12 20 28 36 44 52 60
 | ||||
| 	// 2 10 18 26 34 42 50 58
 | ||||
| 	// 0  8 16 24 32 40 48 56
 | ||||
| 	// 7 15 23 31 39 47 55 63
 | ||||
| 	// 5 13 21 29 37 45 53 61
 | ||||
| 	// 3 11 19 27 35 43 51 59
 | ||||
| 	// 1  9 17 25 33 41 49 57
 | ||||
| 	return block | ||||
| } | ||||
| 
 | ||||
| // permuteInitial_block is equivalent to the permutation defined
 | ||||
| // by finalPermutation.
 | ||||
| fn permute_final_block(b u64) u64 { | ||||
| 	// Perform the same bit exchanges as permuteInitial_block
 | ||||
| 	// but in reverse order.
 | ||||
| 	mut block := b | ||||
| 	mut b1 := block & 0xaaaaaaaa55555555 | ||||
| 	block ^= b1 ^ b1 >> 33 ^ b1 << 33 | ||||
| 
 | ||||
| 	b1 = block & 0x3300330033003300 | ||||
| 	mut b2 := block & 0x00cc00cc00cc00cc | ||||
| 	block ^= b1 ^ b2 ^ b1 >> 6 ^ b2 << 6 | ||||
| 
 | ||||
| 	b1 = block & 0x0f0f00000f0f0000 | ||||
| 	b2 = block & 0x0000f0f00000f0f0 | ||||
| 	block ^= b1 ^ b2 ^ b1 >> 12 ^ b2 << 12 | ||||
| 
 | ||||
| 	b1 = block >> 32 & 0xff00ff | ||||
| 	b2 = (block & 0xff00ff00) | ||||
| 	block ^= b1 << 32 ^ b2 ^ b1 << 8 ^ b2 << 24 | ||||
| 
 | ||||
| 	b1 = block >> 48 | ||||
| 	b2 = block << 48 | ||||
| 	block ^= b1 ^ b2 ^ b1 << 48 ^ b2 >> 48 | ||||
| 	return block | ||||
| } | ||||
| 
 | ||||
| // creates 16 28-bit blocks rotated according
 | ||||
| // to the rotation schedule
 | ||||
| fn ks_rotate(ain u32) []u32 { | ||||
| 	mut out := []u32{len: 16} | ||||
| 	mut last := ain | ||||
| 	for i := 0; i < 16; i++ { | ||||
| 		// 28-bit circular left shift
 | ||||
| 		left := (last << (4 + ks_rotations[i])) >> 4 | ||||
| 		right := (last << 4) >> (32 - ks_rotations[i]) | ||||
| 		out[i] = left | right | ||||
| 		last = out[i] | ||||
| 	} | ||||
| 	return out | ||||
| } | ||||
| 
 | ||||
| // Expand 48-bit input to 64-bit, with each 6-bit block padded by extra two bits at the top.
 | ||||
| // By doing so, we can have the input blocks (four bits each), and the key blocks (six bits each) well-aligned without
 | ||||
| // extra shifts/rotations for alignments.
 | ||||
| fn unpack(x u64) u64 { | ||||
| 	return ((x >> (6 * 1)) & 0xff) << (8 * 0) | ((x >> (6 * 3)) & 0xff) << (8 * 1) | ((x >> (6 * 5)) & 0xff) << (8 * 2) | ((x >> (6 * 7)) & 0xff) << (8 * 3) | ((x >> (6 * 0)) & 0xff) << (8 * 4) | ((x >> (6 * 2)) & 0xff) << (8 * 5) | ((x >> (6 * 4)) & 0xff) << (8 * 6) | ((x >> (6 * 6)) & 0xff) << (8 * 7) | ||||
| } | ||||
|  | @ -0,0 +1,154 @@ | |||
| // The source code refers to the go standard library, which can be merged with AES later
 | ||||
| 
 | ||||
| // Package des implements the Data Encryption Standard (DES) and the
 | ||||
| // Triple Data Encryption Algorithm (TDEA) as defined
 | ||||
| // in U.S. Federal Information Processing Standards Publication 46-3.
 | ||||
| //
 | ||||
| // DES is cryptographically broken and should not be used for secure
 | ||||
| // applications.
 | ||||
| 
 | ||||
| module des | ||||
| 
 | ||||
| // Used to perform an initial permutation of a 64-bit input block.
 | ||||
| // const initial_permutation = [byte(6), 14, 22, 30, 38, 46, 54, 62, 4, 12, 20, 28, 36, 44, 52, 60,
 | ||||
| // 	2, 10, 18, 26, 34, 42, 50, 58, 0, 8, 16, 24, 32, 40, 48, 56, 7, 15, 23, 31, 39, 47, 55, 63,
 | ||||
| // 	5, 13, 21, 29, 37, 45, 53, 61, 3, 11, 19, 27, 35, 43, 51, 59, 1, 9, 17, 25, 33, 41, 49, 57]
 | ||||
| 
 | ||||
| // // Used to perform a final permutation of a 4-bit preoutput block. This is the
 | ||||
| // // inverse of initialPermutation
 | ||||
| // const final_permutation = [byte(24), 56, 16, 48, 8, 40, 0, 32, 25, 57, 17, 49, 9, 41, 1, 33, 26,
 | ||||
| // 	58, 18, 50, 10, 42, 2, 34, 27, 59, 19, 51, 11, 43, 3, 35, 28, 60, 20, 52, 12, 44, 4, 36, 29,
 | ||||
| // 	61, 21, 53, 13, 45, 5, 37, 30, 62, 22, 54, 14, 46, 6, 38, 31, 63, 23, 55, 15, 47, 7, 39]
 | ||||
| 
 | ||||
| // // Used to expand an input block of 32 bits, producing an output block of 48
 | ||||
| // // bits.
 | ||||
| // const expansion_function = [byte(0), 31, 30, 29, 28, 27, 28, 27, 26, 25, 24, 23, 24, 23, 22, 21,
 | ||||
| // 	20, 19, 20, 19, 18, 17, 16, 15, 16, 15, 14, 13, 12, 11, 12, 11, 10, 9, 8, 7, 8, 7, 6, 5, 4,
 | ||||
| // 	3, 4, 3, 2, 1, 0, 31]
 | ||||
| 
 | ||||
| // // Yields a 32-bit output from a 32-bit input
 | ||||
| // const permutation_function = [byte(16), 25, 12, 11, 3, 20, 4, 15, 31, 17, 9, 6, 27, 14, 1, 22,
 | ||||
| // 	30, 24, 8, 18, 0, 5, 29, 23, 13, 19, 2, 26, 10, 21, 28, 7]
 | ||||
| 
 | ||||
| // Used in the key schedule to select 56 bits
 | ||||
| // from a 64-bit input.
 | ||||
| const permuted_choice1 = [byte(7), 15, 23, 31, 39, 47, 55, 63, 6, 14, 22, 30, 38, 46, 54, 62, 5, | ||||
| 	13, 21, 29, 37, 45, 53, 61, 4, 12, 20, 28, 1, 9, 17, 25, 33, 41, 49, 57, 2, 10, 18, 26, 34, | ||||
| 	42, 50, 58, 3, 11, 19, 27, 35, 43, 51, 59, 36, 44, 52, 60] | ||||
| 
 | ||||
| // Used in the key schedule to produce each subkey by selecting 48 bits from
 | ||||
| // the 56-bit input
 | ||||
| const permuted_choice2 = [byte(42), 39, 45, 32, 55, 51, 53, 28, 41, 50, 35, 46, 33, 37, 44, 52, | ||||
| 	30, 48, 40, 49, 29, 36, 43, 54, 15, 4, 25, 19, 9, 1, 26, 16, 5, 11, 23, 8, 12, 7, 17, 0, 22, | ||||
| 	3, 10, 14, 6, 20, 27, 24] | ||||
| 
 | ||||
| // 8 S-boxes composed of 4 rows and 16 columns
 | ||||
| // Used in the DES cipher function
 | ||||
| // const s_boxes = [
 | ||||
| // 	[
 | ||||
| // 		[u8(14), 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7],
 | ||||
| // 		[u8(0), 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8],
 | ||||
| // 		[u8(4), 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0],
 | ||||
| // 		[u8(15), 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13],
 | ||||
| // 	],
 | ||||
| // 	[
 | ||||
| // 		[u8(15), 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10],
 | ||||
| // 		[u8(3), 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5],
 | ||||
| // 		[u8(0), 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15],
 | ||||
| // 		[u8(13), 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9],
 | ||||
| // 	],
 | ||||
| // 	[
 | ||||
| // 		[u8(10), 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8],
 | ||||
| // 		[u8(13), 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1],
 | ||||
| // 		[u8(13), 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7],
 | ||||
| // 		[u8(1), 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12],
 | ||||
| // 	],
 | ||||
| // 	[
 | ||||
| // 		[u8(7), 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15],
 | ||||
| // 		[u8(13), 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9],
 | ||||
| // 		[u8(10), 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4],
 | ||||
| // 		[u8(3), 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14],
 | ||||
| // 	],
 | ||||
| // 	[
 | ||||
| // 		[u8(2), 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9],
 | ||||
| // 		[u8(14), 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6],
 | ||||
| // 		[u8(4), 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14],
 | ||||
| // 		[u8(11), 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3],
 | ||||
| // 	],
 | ||||
| // 	[
 | ||||
| // 		[u8(12), 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11],
 | ||||
| // 		[u8(10), 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8],
 | ||||
| // 		[u8(9), 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6],
 | ||||
| // 		[u8(4), 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13],
 | ||||
| // 	],
 | ||||
| // 	[
 | ||||
| // 		[u8(4), 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1],
 | ||||
| // 		[u8(13), 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6],
 | ||||
| // 		[u8(1), 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2],
 | ||||
| // 		[u8(6), 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12],
 | ||||
| // 	],
 | ||||
| // 	[
 | ||||
| // 		[u8(13), 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7],
 | ||||
| // 		[u8(1), 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2],
 | ||||
| // 		[u8(7), 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8],
 | ||||
| // 		[u8(2), 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11],
 | ||||
| // 	],
 | ||||
| // ]
 | ||||
| 
 | ||||
| const feistel_box = [ | ||||
| 	[u32(16843776), 0, 65536, 16843780, 16842756, 66564, 4, 65536, 1024, 16843776, 16843780, 1024, | ||||
| 		16778244, 16842756, 16777216, 4, 1028, 16778240, 16778240, 66560, 66560, 16842752, 16842752, | ||||
| 		16778244, 65540, 16777220, 16777220, 65540, 0, 1028, 66564, 16777216, 65536, 16843780, | ||||
| 		4, 16842752, 16843776, 16777216, 16777216, 1024, 16842756, 65536, 66560, 16777220, 1024, | ||||
| 		4, 16778244, 66564, 16843780, 65540, 16842752, 16778244, 16777220, 1028, 66564, 16843776, | ||||
| 		1028, 16778240, 16778240, 0, 65540, 66560, 0, 16842756], | ||||
| 	[u32(2148565024), 2147516416, 32768, 1081376, 1048576, 32, 2148532256, 2147516448, 2147483680, | ||||
| 		2148565024, 2148564992, 2147483648, 2147516416, 1048576, 32, 2148532256, 1081344, 1048608, | ||||
| 		2147516448, 0, 2147483648, 32768, 1081376, 2148532224, 1048608, 2147483680, 0, 1081344, | ||||
| 		32800, 2148564992, 2148532224, 32800, 0, 1081376, 2148532256, 1048576, 2147516448, 2148532224, | ||||
| 		2148564992, 32768, 2148532224, 2147516416, 32, 2148565024, 1081376, 32, 32768, 2147483648, | ||||
| 		32800, 2148564992, 1048576, 2147483680, 1048608, 2147516448, 2147483680, 1048608, 1081344, | ||||
| 		0, 2147516416, 32800, 2147483648, 2148532256, 2148565024, 1081344], | ||||
| 	[u32(520), 134349312, 0, 134348808, 134218240, 0, 131592, 134218240, 131080, 134217736, 134217736, | ||||
| 		131072, 134349320, 131080, 134348800, 520, 134217728, 8, 134349312, 512, 131584, 134348800, | ||||
| 		134348808, 131592, 134218248, 131584, 131072, 134218248, 8, 134349320, 512, 134217728, | ||||
| 		134349312, 134217728, 131080, 520, 131072, 134349312, 134218240, 0, 512, 131080, 134349320, | ||||
| 		134218240, 134217736, 512, 0, 134348808, 134218248, 131072, 134217728, 134349320, 8, 131592, | ||||
| 		131584, 134217736, 134348800, 134218248, 520, 134348800, 131592, 8, 134348808, 131584], | ||||
| 	[u32(8396801), 8321, 8321, 128, 8396928, 8388737, 8388609, 8193, 0, 8396800, 8396800, 8396929, | ||||
| 		129, 0, 8388736, 8388609, 1, 8192, 8388608, 8396801, 128, 8388608, 8193, 8320, 8388737, | ||||
| 		1, 8320, 8388736, 8192, 8396928, 8396929, 129, 8388736, 8388609, 8396800, 8396929, 129, | ||||
| 		0, 0, 8396800, 8320, 8388736, 8388737, 1, 8396801, 8321, 8321, 128, 8396929, 129, 1, 8192, | ||||
| 		8388609, 8193, 8396928, 8388737, 8193, 8320, 8388608, 8396801, 128, 8388608, 8192, 8396928], | ||||
| 	[u32(256), 34078976, 34078720, 1107296512, 524288, 256, 1073741824, 34078720, 1074266368, 524288, | ||||
| 		33554688, 1074266368, 1107296512, 1107820544, 524544, 1073741824, 33554432, 1074266112, | ||||
| 		1074266112, 0, 1073742080, 1107820800, 1107820800, 33554688, 1107820544, 1073742080, 0, | ||||
| 		1107296256, 34078976, 33554432, 1107296256, 524544, 524288, 1107296512, 256, 33554432, | ||||
| 		1073741824, 34078720, 1107296512, 1074266368, 33554688, 1073741824, 1107820544, 34078976, | ||||
| 		1074266368, 256, 33554432, 1107820544, 1107820800, 524544, 1107296256, 1107820800, 34078720, | ||||
| 		0, 1074266112, 1107296256, 524544, 33554688, 1073742080, 524288, 0, 1074266112, 34078976, | ||||
| 		1073742080], | ||||
| 	[u32(536870928), 541065216, 16384, 541081616, 541065216, 16, 541081616, 4194304, 536887296, | ||||
| 		4210704, 4194304, 536870928, 4194320, 536887296, 536870912, 16400, 0, 4194320, 536887312, | ||||
| 		16384, 4210688, 536887312, 16, 541065232, 541065232, 0, 4210704, 541081600, 16400, 4210688, | ||||
| 		541081600, 536870912, 536887296, 16, 541065232, 4210688, 541081616, 4194304, 16400, 536870928, | ||||
| 		4194304, 536887296, 536870912, 16400, 536870928, 541081616, 4210688, 541065216, 4210704, | ||||
| 		541081600, 0, 541065232, 16, 16384, 541065216, 4210704, 16384, 4194320, 536887312, 0, | ||||
| 		541081600, 536870912, 4194320, 536887312], | ||||
| 	[u32(2097152), 69206018, 67110914, 0, 2048, 67110914, 2099202, 69208064, 69208066, 2097152, | ||||
| 		0, 67108866, 2, 67108864, 69206018, 2050, 67110912, 2099202, 2097154, 67110912, 67108866, | ||||
| 		69206016, 69208064, 2097154, 69206016, 2048, 2050, 69208066, 2099200, 2, 67108864, 2099200, | ||||
| 		67108864, 2099200, 2097152, 67110914, 67110914, 69206018, 69206018, 2, 2097154, 67108864, | ||||
| 		67110912, 2097152, 69208064, 2050, 2099202, 69208064, 2050, 67108866, 69208066, 69206016, | ||||
| 		2099200, 0, 2, 69208066, 0, 2099202, 69206016, 2048, 67108866, 67110912, 2048, 2097154], | ||||
| 	[u32(268439616), 4096, 262144, 268701760, 268435456, 268439616, 64, 268435456, 262208, 268697600, | ||||
| 		268701760, 266240, 268701696, 266304, 4096, 64, 268697600, 268435520, 268439552, 4160, | ||||
| 		266240, 262208, 268697664, 268701696, 4160, 0, 0, 268697664, 268435520, 268439552, 266304, | ||||
| 		262144, 266304, 262144, 268701696, 4096, 64, 268697664, 4096, 266304, 268439552, 64, | ||||
| 		268435520, 268697600, 268697664, 268435456, 262144, 268439616, 0, 268701760, 262208, | ||||
| 		268435520, 268697600, 268439552, 268439616, 0, 268701760, 266240, 266240, 4160, 4160, 262208, | ||||
| 		268435456, 268701696], | ||||
| ] | ||||
| 
 | ||||
| // Size of left rotation per round in each half of the key schedule
 | ||||
| const ks_rotations = [u8(1), 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1] | ||||
|  | @ -0,0 +1,169 @@ | |||
| // The source code refers to the go standard library
 | ||||
| 
 | ||||
| module des | ||||
| 
 | ||||
| import crypto.cipher | ||||
| import crypto.internal.subtle | ||||
| import encoding.binary | ||||
| 
 | ||||
| const block_size = 8 | ||||
| 
 | ||||
| // A tripleDesCipher is an instance of TripleDES encryption.
 | ||||
| struct TripleDesCipher { | ||||
| 	block_size int = des.block_size | ||||
| mut: | ||||
| 	cipher1 DesCipher | ||||
| 	cipher2 DesCipher | ||||
| 	cipher3 DesCipher | ||||
| } | ||||
| 
 | ||||
| // DesCipher is an instance of DES encryption.
 | ||||
| struct DesCipher { | ||||
| 	block_size int = des.block_size | ||||
| mut: | ||||
| 	subkeys [16]u64 | ||||
| } | ||||
| 
 | ||||
| // NewCipher creates and returns a new cipher.Block.
 | ||||
| pub fn new_cipher(key []byte) cipher.Block { | ||||
| 	if key.len != 8 { | ||||
| 		panic('crypto.aes: invalid key size') | ||||
| 	} | ||||
| 
 | ||||
| 	mut c := DesCipher{} | ||||
| 	c.generate_subkeys(key) | ||||
| 	return c | ||||
| } | ||||
| 
 | ||||
| // creates 16 56-bit subkeys from the original key
 | ||||
| fn (mut c DesCipher) generate_subkeys(key_bytes []byte) { | ||||
| 	// feistel_box_once.do(initFeistel_box)
 | ||||
| 
 | ||||
| 	// apply PC1 permutation to key
 | ||||
| 	key := binary.big_endian_u64(key_bytes) | ||||
| 	permuted_key := permute_block(key, permuted_choice1[..]) | ||||
| 
 | ||||
| 	// rotate halves of permuted key according to the rotation schedule
 | ||||
| 	left_rotations := ks_rotate(u32(permuted_key >> 28)) | ||||
| 	right_rotations := ks_rotate(u32(permuted_key << 4) >> 4) | ||||
| 
 | ||||
| 	// generate subkeys
 | ||||
| 	for i := 0; i < 16; i++ { | ||||
| 		// combine halves to form 56-bit input to PC2
 | ||||
| 		pc2_input := u64(left_rotations[i]) << 28 | u64(right_rotations[i]) | ||||
| 		// apply PC2 permutation to 7 byte input
 | ||||
| 		c.subkeys[i] = unpack(permute_block(pc2_input, permuted_choice2[..])) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| pub fn (c &DesCipher) encrypt(mut dst []byte, src []byte) { | ||||
| 	if src.len < des.block_size { | ||||
| 		panic('crypto/des: input not full block') | ||||
| 	} | ||||
| 	if dst.len < des.block_size { | ||||
| 		panic('crypto/des: output not full block') | ||||
| 	} | ||||
| 	if subtle.inexact_overlap(dst[..des.block_size], src[..des.block_size]) { | ||||
| 		panic('crypto/des: invalid buffer overlap') | ||||
| 	} | ||||
| 	encrypt_block(c.subkeys[..], mut dst, src) | ||||
| } | ||||
| 
 | ||||
| pub fn (c &DesCipher) decrypt(mut dst []byte, src []byte) { | ||||
| 	if src.len < des.block_size { | ||||
| 		panic('crypto/des: input not full block') | ||||
| 	} | ||||
| 	if dst.len < des.block_size { | ||||
| 		panic('crypto/des: output not full block') | ||||
| 	} | ||||
| 	if subtle.inexact_overlap(dst[..des.block_size], src[..des.block_size]) { | ||||
| 		panic('crypto/des: invalid buffer overlap') | ||||
| 	} | ||||
| 	decrypt_block(c.subkeys[..], mut dst, src) | ||||
| } | ||||
| 
 | ||||
| // NewTripleDesCipher creates and returns a new cipher.Block.
 | ||||
| pub fn new_triple_des_cipher(key []byte) cipher.Block { | ||||
| 	if key.len != 24 { | ||||
| 		panic('crypto.des: invalid key size') | ||||
| 	} | ||||
| 	mut c := TripleDesCipher{} | ||||
| 	c.cipher1.generate_subkeys(key[..8]) | ||||
| 	c.cipher2.generate_subkeys(key[8..16]) | ||||
| 	c.cipher3.generate_subkeys(key[16..]) | ||||
| 	return c | ||||
| } | ||||
| 
 | ||||
| pub fn (c &TripleDesCipher) encrypt(mut dst []byte, src []byte) { | ||||
| 	if src.len < des.block_size { | ||||
| 		panic('crypto/des: input not full block') | ||||
| 	} | ||||
| 	if dst.len < des.block_size { | ||||
| 		panic('crypto/des: output not full block') | ||||
| 	} | ||||
| 	if subtle.inexact_overlap(dst[..des.block_size], src[..des.block_size]) { | ||||
| 		panic('crypto/des: invalid buffer overlap') | ||||
| 	} | ||||
| 
 | ||||
| 	mut b := binary.big_endian_u64(src) | ||||
| 	b = permute_initial_block(b) | ||||
| 	mut left, mut right := u32(b >> 32), u32(b) | ||||
| 
 | ||||
| 	left = (left << 1) | (left >> 31) | ||||
| 	right = (right << 1) | (right >> 31) | ||||
| 
 | ||||
| 	for i := 0; i < 8; i++ { | ||||
| 		left, right = feistel(left, right, c.cipher1.subkeys[2 * i], c.cipher1.subkeys[2 * i + 1]) | ||||
| 	} | ||||
| 	for i := 0; i < 8; i++ { | ||||
| 		right, left = feistel(right, left, c.cipher2.subkeys[15 - 2 * i], c.cipher2.subkeys[15 - ( | ||||
| 			2 * i + 1)]) | ||||
| 	} | ||||
| 	for i := 0; i < 8; i++ { | ||||
| 		left, right = feistel(left, right, c.cipher3.subkeys[2 * i], c.cipher3.subkeys[2 * i + 1]) | ||||
| 	} | ||||
| 
 | ||||
| 	left = (left << 31) | (left >> 1) | ||||
| 	right = (right << 31) | (right >> 1) | ||||
| 
 | ||||
| 	pre_output := (u64(right) << 32) | u64(left) | ||||
| 	binary.big_endian_put_u64(mut dst, permute_final_block(pre_output)) | ||||
| } | ||||
| 
 | ||||
| pub fn (c &TripleDesCipher) decrypt(mut dst []byte, src []byte) { | ||||
| 	if src.len < des.block_size { | ||||
| 		panic('crypto/des: input not full block') | ||||
| 	} | ||||
| 	if dst.len < des.block_size { | ||||
| 		panic('crypto/des: output not full block') | ||||
| 	} | ||||
| 	if subtle.inexact_overlap(dst[..des.block_size], src[..des.block_size]) { | ||||
| 		panic('crypto/des: invalid buffer overlap') | ||||
| 	} | ||||
| 
 | ||||
| 	mut b := binary.big_endian_u64(src) | ||||
| 	b = permute_initial_block(b) | ||||
| 
 | ||||
| 	mut left, mut right := u32(b >> 32), u32(b) | ||||
| 
 | ||||
| 	left = (left << 1) | (left >> 31) | ||||
| 	right = (right << 1) | (right >> 31) | ||||
| 
 | ||||
| 	for i := 0; i < 8; i++ { | ||||
| 		left, right = feistel(left, right, c.cipher3.subkeys[15 - 2 * i], c.cipher3.subkeys[15 - ( | ||||
| 			2 * i + 1)]) | ||||
| 	} | ||||
| 	for i := 0; i < 8; i++ { | ||||
| 		right, left = feistel(right, left, c.cipher2.subkeys[2 * i], c.cipher2.subkeys[2 * i + 1]) | ||||
| 	} | ||||
| 	for i := 0; i < 8; i++ { | ||||
| 		left, right = feistel(left, right, c.cipher1.subkeys[15 - 2 * i], c.cipher1.subkeys[15 - ( | ||||
| 			2 * i + 1)]) | ||||
| 	} | ||||
| 
 | ||||
| 	left = (left << 31) | (left >> 1) | ||||
| 	right = (right << 31) | (right >> 1) | ||||
| 
 | ||||
| 	pre_output := (u64(right) << 32) | u64(left) | ||||
| 	binary.big_endian_put_u64(mut dst, permute_final_block(pre_output)) | ||||
| } | ||||
|  | @ -0,0 +1,51 @@ | |||
| import crypto.des | ||||
| 
 | ||||
| const ( | ||||
| 	key = '123456789012345678901234'.bytes() | ||||
| 	iv  = 'abcdegfh'.bytes() | ||||
| 	str = 'aaaaaaaa' | ||||
| ) | ||||
| 
 | ||||
| fn test_triple_des() { | ||||
| 	mut src := str.bytes() | ||||
| 
 | ||||
| 	triple_des_en(mut src, key, iv) | ||||
| 	assert src.hex() == '45902cf00aa1df46' | ||||
| 
 | ||||
| 	triple_des_de(mut src, key, iv) | ||||
| 	assert src.bytestr() == str | ||||
| 	println('test_triple_des ok') | ||||
| } | ||||
| 
 | ||||
| fn test_des() { | ||||
| 	mut src := str.bytes() | ||||
| 
 | ||||
| 	des_en(mut src, key[..8], iv) | ||||
| 	assert src.hex() == '72dca13c37223cf0' | ||||
| 
 | ||||
| 	des_de(mut src, key[..8], iv) | ||||
| 	assert src.bytestr() == str | ||||
| 
 | ||||
| 	println('test_des ok') | ||||
| } | ||||
| 
 | ||||
| fn des_en(mut src []byte, key []byte, iv []byte) { | ||||
| 	block := des.new_cipher(key) | ||||
| 	block.encrypt(mut src, src.clone()) | ||||
| } | ||||
| 
 | ||||
| fn des_de(mut src []byte, key []byte, iv []byte) { | ||||
| 	block := des.new_cipher(key) | ||||
| 	block.decrypt(mut src, src.clone()) | ||||
| } | ||||
| 
 | ||||
| fn triple_des_en(mut src []byte, key []byte, iv []byte) { | ||||
| 	block := des.new_triple_des_cipher(key) | ||||
| 	block.encrypt(mut src, src.clone()) | ||||
| } | ||||
| 
 | ||||
| fn triple_des_de(mut src []byte, key []byte, iv []byte) { | ||||
| 	block := des.new_triple_des_cipher(key) | ||||
| 	inbuf := src.clone() | ||||
| 	block.decrypt(mut src, inbuf) | ||||
| } | ||||
		Loading…
	
		Reference in New Issue