Simplified-DES的实现

题目描述

实验目的

1) 学习S-DES密码算法的原理

2) 掌握S-DES密码算法的实现

实验原理

1) 算法原理

Simplified DES方案,简称S-DES方案,是DES算法的简化版。它是一个供教学而非安全的加密算法,它与DES的特性和结构类似,但参数小。

加密算法涉及五个函数:

(1)初始置换IP(initial permutation)

(2)复合函数fk1,它是由密钥K确定的,具有置换和代换的运算。

(3)置换函数SW

(4)复合函数fk2

(5)初始置换IP的逆置换IP-1

[图片上传失败...(image-13062e-1668674986761)]

image.png
image.png
image.png

2) 算法参数——S-DES所需的几个置换表

① P10={3,5,2,7,4,10,1,9,8,6}

② P8={6,3,7,4,8,5,10,9} 注意这个置换选择输入10位输出8位

③ P4={2,4,3,1}

④ IP={2,6,3,1,4,8,5,7}

⑤ IP-1={4,1,3,5,7,2,8,6}

⑥ EP={4,1,2,3,2,3,4,1} 注意这个是扩展置换,输入4位输出8位

⑦ 两个S盒:

S0:

{1,0,3,2}

{3,2,1,0}

{0,2,1,3}

{3,1,3,2}

S1:

{0,1,2,3}

{2,0,1,3}

{3,0,1,0}

{2,1,0,3}

3) 算法说明

若明文为: m=0001 0110, key选为(01111 11101),给出加密过程和解密过程,并计算出密文和明文。

a)子密钥的生成

① 10位密钥key = 01111 11101

② 对key做P10置换(P10={3,5,2,7,4,10,1,9,8,6})得到 11111 10011

③ 记左半(高位)的为Lk=11111,右半(低位)为Rk=10011

④ LS-1:Lk和Rk均循环左移1位,得到Lk=11111,Rk=00111

⑤ 对Lk和Rk组合得到的11111 00111做P8置换(P8={6,3,7,4,8,5,10,9})选择,得到子密钥K1=0101 1111

⑥ LS-2:Lk和Rk均再次循环左移2位,得到Lk=11111,Rk=11100

⑦ P8:对Lk和Rk组合得到的11111 11100做P8置换选择,得到子密钥K2=1111 1100

以上,通过密钥得到了算法所需的子密钥。

b)加密过程

首先是初始置换

① 对明文m=0001 0110做IP置换(IP={2,6,3,1,4,8,5,7}),得m’=0100 1001

接下来是标准的Feistel密码结构,共有两次循环。

第一次循环

② 记左半(高位)为Lm=0100,右半(低位)为Rm=1001

③ 对Rm做EP扩展置换(EP={4,1,2,3,2,3,4,1}),得Rm’=1100 0011

④ Rm’与子密钥K1按位异或(K1=0101 1111),得Rm’=1001 1100

⑤ Rm’左半1001(A1A2A3A4)进入S0盒替代选择得11(第4行A1A4 /第1列A2A3的数字3,再转成二进制11,A1A4中A1是数位高位),右半1100进入S1盒替代选择的01(第3行10/第3列10的数字1),组合后得Rm’=1101

⑥ 对Rm’做P4置换(P4={2,4,3,1}),得Rm’=1101

⑦ Rm’与Lm按位异或,得Lm’=1001

⑧ Lm’与Rm(最开始的那个Rm)组合得到输出 1001(Lm’) 1001(Rm)

至此完成第一次循环。

⑨ 然后交换高低位,作为第二次循环的输入,即1001(Rm)1001(Lm’)作为输入

开始第二次循环

⑩ 记左半为Ln=1001,右半为Rn=1001

11 对Rn做EP扩展置换(EP={4,1,2,3,2,3,4,1}),得Rn’=1100 0011

12 Rn’与子密钥K2按位异或(K2=1111 1100),得Rn’=0011 1111

13 Rn’左半0011进入S0盒替代选择得10(第2行01/第2列01的数字2,再转成二进制10),右半1111进入S1盒替代选择的11(第4行11/第4列11的数字3,再转成二进制11),组合后得Rn’=1011

14 对Rn’做P4置换(P4={2,4,3,1}),得Rn’=0111

15 Rn’与Ln按位异或,得Ln’=1110

16 Ln’与Rn(最开始的那个Rn)组合得到输出 1110(Ln’) 1001(Rn)

至此完成第二次循环

17 最后进行逆初始置换对上面的输出m’=1110 1001做IP-1置换得到密文m’=0111 0110.

OK,到这里就完成了将明文加密为密文,S-DES加密结束。

c)解密过程

解密过程与加密基本一致,就是密钥使用顺序是相反的,第一次循环使用K2第二次循环使用K1。

首先还是初始置换

① 对密文m=0111 0110做IP置换(IP={2,6,3,1,4,8,5,7}),得m’=1110 1001

Feistel密码结构

第一次循环

② 记左半(高位)为Lm=1110,右半(低位)为Rm=1001

③ 对Rm做EP扩展置换(EP={4,1,2,3,2,3,4,1}),得Rm’=1100 0011

④ Rm’与子密钥K2按位异或(K2=1111 1100),得Rm’=0011 1111

⑤ Rm’左半0011进入S0盒替代选择得10(第2行01/第2列01的数字2,再转成二进制10),右半1111进入S1盒替代选择的11(第4行11/第4列11的数字3,再转成二进制11),组合后得Rm’=1011

⑥ 对Rm’做P4置换(P4={2,4,3,1}),得Rm’=0111

⑦ Rm’与Lm按位异或,得Lm’=1001

⑧ Lm’与Rm(最开始的那个Rm)组合得到输出 1001(Lm’) 1001(Rm)

至此完成第一次循环。

⑨ 然后交换高低位,作为第二次循环的输入,即1001(Rm) 1001(Lm’)作为输入

开始第二次循环

⑩ 记左半为Ln=1001,右半为Rn=1001

11 对Rn做EP扩展置换(EP={4,1,2,3,2,3,4,1}),得Rn’=1100 0011

12 Rn’与子密钥K1按位异或(K1=0101 1111),得Rn’=1001 1100

13 Rn’左半1001进入S0盒替代选择得11(第4行11/第1列00的数字3,再转成二进制11),右半1100进入S1盒替代选择的01(第3行10/第3列10的数字1),组合后得Rn’=1101

14 对Rn’做P4置换(P4={2,4,3,1}),得Rn’=1101

15 Rn’与Ln按位异或,得Ln’=0100

16 Ln’与Rn(最开始的那个Rn)组合得到输出0100(Ln’) 1001(Rn)

至此完成第二次循环。

17 最后进行逆初始置换

18 对上面的输出m’=0100 1001做IP-1置换(IP-1={4,1,3,5,7,2,8,6})得到明文m’=0001 0110.

这样就完成的S-DES的解密。

输入

第一行输入主密钥

第二行输入明文

输出

输出密文

输入样例

1100011110
00101000
0111111101
00010110

输出样例

10001010
01110110

解题

这里先贴代码,因为当初我按照一步一步来,没有分模块。可能是一种面向过程的编程。

package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
    "strconv"
    "strings"
)

func id193(_r io.Reader, _w io.Writer) {
    in := bufio.NewReader(_r)
    out := bufio.NewWriter(_w)
    defer out.Flush()

    var key, text string
    P10 := []int{3, 5, 2, 7, 4, 10, 1, 9, 8, 6}
    P8 := []int{6, 3, 7, 4, 8, 5, 10, 9}
    P4 := []int{2, 4, 3, 1}
    IP := []int{2, 6, 3, 1, 4, 8, 5, 7}
    IP1 := []int{4, 1, 3, 5, 7, 2, 8, 6}
    S0 := [][]string{{"01", "01", "11", "10"},
        {"11", "10", "01", "00"},
        {"00", "10", "01", "11"},
        {"11", "01", "11", "10"}}
    S1 := [][]string{{"00", "01", "10", "11"},
        {"10", "00", "01", "11"},
        {"11", "00", "01", "00"},
        {"10", "01", "00", "11"}}
    EP := []int{4, 1, 2, 3, 2, 3, 4, 1}
    for {
        if _, err := fmt.Fscan(in, &key, &text); err != io.EOF {
            var convP10 strings.Builder
            for i := range P10 {
                fmt.Fprint(&convP10, string(key[P10[i]-1]))
            }
            Lk := convP10.String()[1:5] + convP10.String()[0:1]
            Rk := convP10.String()[6:] + convP10.String()[5:6]
            key2 := Lk + Rk
            var convP8 strings.Builder
            for i := range P8 {
                fmt.Fprint(&convP8, string(key2[P8[i]-1]))
            }
            K1 := convP8.String()
            key2 = Lk[2:5] + Lk[0:2] + Rk[2:5] + Rk[0:2]
            var K2_ strings.Builder
            for i := range P8 {
                fmt.Fprint(&K2_, string(key2[P8[i]-1]))
            }
            K2 := K2_.String()
            // fmt.Println(K1, K2)
            var convText_ strings.Builder
            for i := range IP {
                fmt.Fprint(&convText_, string(text[IP[i]-1]))
            }
            Lm := convText_.String()[:4]
            Rm := convText_.String()[4:]
            Rm_ := []int{}
            for i := range EP {
                v, err := strconv.Atoi(string(Rm[EP[i]-1]))
                if err == nil {
                    Rm_ = append(Rm_, v)
                }

            }
            // fmt.Println(Rm_)
            for i := range Rm_ {
                v, _ := strconv.Atoi(string(K1[i]))
                Rm_[i] ^= v
            }
            // fmt.Println(Rm_)
            Rm1 := S0[Rm_[0]*2+Rm_[3]][Rm_[1]*2+Rm_[2]]
            Rm2 := S1[Rm_[4]*2+Rm_[7]][Rm_[5]*2+Rm_[6]]
            var Lm_ []int
            Rm__ := Rm1 + Rm2
            for i := range P4 {
                tmp1, _ := strconv.Atoi(string(Rm__[P4[i]-1]))
                tmp2, _ := strconv.Atoi(string(Lm[i]))
                Lm_ = append(Lm_, tmp1^tmp2)
            }
            // fmt.Println(Lm_, Rm)
            Rn_ := []int{}
            for i := range EP {
                v, _ := strconv.Atoi(string(K2[i]))
                Rn_ = append(Rn_, Lm_[EP[i]-1]^v)
            }
            Rn1 := S0[Rn_[0]*2+Rn_[3]][Rn_[1]*2+Rn_[2]]
            Rn2 := S1[Rn_[4]*2+Rn_[7]][Rn_[5]*2+Rn_[6]]
            res := ""
            for i := range P4 {
                v, _ := strconv.Atoi(string((Rn1 + Rn2)[P4[i]-1]))

                b, _ := strconv.Atoi(string(Rm[i]))
                res += strconv.Itoa(v ^ b)
            }
            var ans strings.Builder
            fmt.Fprint(&ans, res)
            for i := range Lm_ {
                v := strconv.Itoa(Lm_[i])
                fmt.Fprint(&ans, v)
            }
            ans1 := ans.String()
            for i := range IP1 {
                fmt.Print(string(ans1[IP1[i]-1]))
            }
            fmt.Println()
        } else {
            break
        }
    }
}

func main() {
    id193(os.Stdin, os.Stdout)
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,194评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,058评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,780评论 0 346
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,388评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,430评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,764评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,907评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,679评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,122评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,459评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,605评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,270评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,867评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,734评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,961评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,297评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,472评论 2 348

推荐阅读更多精彩内容