source: trunk/PKCS1/Library/KuehnSignature.cs @ 1742

Last change on this file since 1742 was 1742, checked in by schomburg, 11 years ago

fixed some bugs
enhanced the GUI
file input possible now

File size: 5.9 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.IO;
6using Org.BouncyCastle.Utilities.Encoders;
7using Org.BouncyCastle.Math;
8using System.Security.Cryptography;
9using Cryptool.PluginBase;
10
11namespace PKCS1.Library
12{
13    class KuehnSignature : Signature, IGuiLogMsg
14    {
15        public KuehnSignature()
16        {
17            this.registerHandOff();
18        }
19
20        public override bool GenerateSignature()
21        {
22            this.m_KeyLength = RSAKeyManager.Instance.RsaKeySize; // Länge des RSA Modulus
23
24            // drei Leerzeichen an Msg anhängen
25            string sMsgModifier = "   ";
26            byte[] bMsgModifier = Encoding.ASCII.GetBytes(sMsgModifier);
27            byte[] bMessage = new byte[ Datablock.getInstance().Message.Length + bMsgModifier.Length ];
28            Array.Copy(Datablock.getInstance().Message, bMessage, Datablock.getInstance().Message.Length);
29            Array.Copy(bMsgModifier, 0, bMessage, Datablock.getInstance().Message.Length, bMsgModifier.Length);
30           
31            HashFunctionIdent hashFuncIdent = Datablock.getInstance().HashFunctionIdent; // Die vom User gewählte Hashfunktion
32            byte[] hashIdent = Hex.Decode(Encoding.ASCII.GetBytes(hashFuncIdent.DERIdent)); // ASN.1 codierter Ident-string
33            int significantByteLength = 11 + hashIdent.Length + hashFuncIdent.digestLength/8;           
34
35            // Datenblock wird konstruiert
36            byte[] A = new byte[significantByteLength];
37            A[0] = 0x00;
38            A[1] = 0x01;
39            for (int i = 2; i < 10; i++)
40            {
41                A[i] = 0xFF;
42            }
43            A[10] = 0x00;         
44            Array.Copy(hashIdent, 0, A, 11, hashIdent.Length);
45            // Datenblock noch ohne Hashwert, wird in while Schleife unten hinzugefügt
46
47            // byte array der kompletten Signatur, wird zuerst mit 'FF' gefüllt und dann nachher Datenblock an den Anfang kopiert
48            byte[] S = new byte[this.m_KeyLength / 8];
49            for (int i = A.Length; i < S.Length; i++)
50            {
51                S[i] = 0xFF;
52            }
53
54            BigInteger finalSignature = null;           
55            int iMsgLength = bMessage.Length;
56            bool isEqual = false;
57            int limit = 250000;
58            int countLoops = 0;
59
60            this.SendGuiLogMsg("Signature Generation started", NotificationLevel.Info);
61            byte[] hashDigest = new byte[0]; // Hashwert wird in dieser var gespeichert
62            BigInteger T = new BigInteger("0"); // hilfsvar
63            byte[] resultArray = new byte[this.m_KeyLength/8];
64
65            while (!isEqual && (countLoops < limit))
66            {
67                hashDigest = Hashfunction.generateHashDigest(ref bMessage, ref hashFuncIdent); // Hashwert wird erzeugt
68                Array.Copy(hashDigest, 0, A, 11 + hashIdent.Length, hashDigest.Length); // erzeugter Hashwert wird in den Datenblock kopiert
69                Array.Copy(A, 0, S, 0, A.Length); // erzeugter Datenblock wird in erzeugte Signatur S kopiert
70
71                finalSignature = MathFunctions.cuberoot4(new BigInteger(S), this.m_KeyLength); // Kubikwurzel ziehen         
72                byte[] test2 = finalSignature.ToByteArray();
73                T = finalSignature.Pow(3); // mit 3 potenzieren       
74                byte[] test = T.ToByteArray();
75                resultArray[0] = 0x00; // erstes byte is 0
76                // durch Konvertierung in BigInteger werden führende Nullen abgeschnitten, daher wird an Stelle 1 in byte array kopiert.
77                Array.Copy(T.ToByteArray(), 0, resultArray, 1, T.ToByteArray().Length);
78
79                isEqual = MathFunctions.compareByteArray(ref resultArray, ref S, significantByteLength); // byte arrays vergleichen, wird in meinen Tests nicht erreicht
80                if (!isEqual)
81                {                                       
82                    int value1 = bMessage[iMsgLength - 1];                                       
83                    if (++value1 >= 256)
84                    {
85                        value1 = 0;
86                        int value2 = bMessage[iMsgLength - 2];
87                        if (++value2 >= 256)
88                        {
89                            value2 = 0;
90                            int value3 = bMessage[iMsgLength - 3];
91                            ++value3;
92                            bMessage[iMsgLength - 3] = (byte)value3;
93                        }
94                        bMessage[iMsgLength - 2] = (byte)value2;
95                    }
96                    bMessage[iMsgLength - 1] = (byte)value1;
97                   
98                    countLoops++;
99                }
100            }
101            if (countLoops != limit)
102            {
103                Datablock.getInstance().Message = bMessage;
104                byte[] returnByteArray = new byte[this.m_KeyLength / 8];
105                Array.Copy(finalSignature.ToByteArray(), 0, returnByteArray, returnByteArray.Length - finalSignature.ToByteArray().Length, finalSignature.ToByteArray().Length);
106
107                this.m_Signature = returnByteArray;
108                this.m_bSigGenerated = true;
109                this.OnRaiseSigGenEvent(SignatureType.Kuehn);
110                return true;
111            }
112            else
113            {
114                this.m_bSigGenerated = false;               
115            }
116            return false;
117        }
118
119        public event GuiLogHandler OnGuiLogMsgSend;
120
121        public void registerHandOff()
122        {
123            GuiLogMsgHandOff.getInstance().registerAt(ref OnGuiLogMsgSend);
124        }
125
126        public void SendGuiLogMsg(string message, NotificationLevel logLevel)
127        {
128            if (null != OnGuiLogMsgSend)
129            {
130                OnGuiLogMsgSend(message, logLevel);
131            }
132        }
133    }
134}
Note: See TracBrowser for help on using the repository browser.