1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

crypto: add a crypto.des module (#13065)

This commit is contained in:
688862
2022-01-07 19:51:37 +08:00
committed by GitHub
parent 7276705684
commit 2b42ea9883
7 changed files with 793 additions and 0 deletions

189
vlib/crypto/des/block.v Normal file
View File

@ -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)
}

154
vlib/crypto/des/const.v Normal file
View File

@ -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]

169
vlib/crypto/des/des.v Normal file
View File

@ -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))
}

View File

@ -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)
}