1-- This program is free software; you can redistribute it and/or 2-- modify it under the terms of the GNU General Public License as 3-- published by the Free Software Foundation; either version 2 of the 4-- License, or (at your option) any later version. 5 6-- This program is distributed in the hope that it will be useful, 7-- but WITHOUT ANY WARRANTY; without even the implied warranty of 8-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9-- General Public License for more details. 10 11-- You should have received a copy of the GNU General Public License 12-- along with this program; if not, write to the Free Software 13-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 14-- 02111-1307, USA. 15 16-- As a special exception, if other files instantiate generics from 17-- this unit, or you link this unit with other files to produce an 18-- executable, this unit does not by itself cause the resulting 19-- executable to be covered by the GNU General Public License. This 20-- exception does not however invalidate any other reasons why the 21-- executable file might be covered by the GNU Public License. 22 23with Crypto.Symmetric.Hashfunction_SHA1; 24 25package body Crypto.Asymmetric.ECDSA is 26 package SHA1 renames Crypto.Symmetric.Hashfunction_SHA1; 27 use Big.Mod_Utils; 28 use Big.Utils; 29 30 31 32------------------------------------------------------------------------------- 33 34 -- check if key is initialited 35 function Is_Init(Key : ECDSA_P_KEY) return Boolean is 36 begin 37 if Key.n /= Big_Unsigned_Zero then 38 return True; 39 else return False; 40 end if; 41 end Is_Init; Pragma Inline (Is_Init); 42 43------------------------------------------------------------------------------- 44 45 -- check if key is initialited 46 function Is_Init(Key : ECDSA_S_KEY) return Boolean is 47 begin 48 if Key.d /= Big_Unsigned_Zero then 49 return True; 50 else return False; 51 end if; 52 end Is_Init; Pragma Inline (Is_Init); 53 54------------------------------------------------------------------------------- 55 56 procedure Gen_Public_Key( 57 Public_Key : out Public_Key_ECDSA; 58 length : in DB.Bit_Length) is 59 begin 60 Get_Elliptic_Curve(Public_Key.E, Public_Key.P, Public_Key.n, length); 61 init(Public_Key.E); 62 end Gen_Public_Key; 63 64 ---------------------------------------------------------------------------- 65 66 procedure Gen_Private_Key( 67 Public_Key : in out Public_Key_ECDSA; 68 Private_Key : out Private_Key_ECDSA) is 69 begin 70 Private_Key.d := Get_Random(Get_P(Public_Key.E) - Big_Unsigned_Three) 71 + Big_Unsigned_One; 72 73 Private_Key.Q := Private_Key.d * Public_Key.P; 74 Public_Key.Q := Private_Key.Q; 75 end Gen_Private_Key; 76 77 ---------------------------------------------------------------------------- 78 79 procedure Sign(Public_Key : in Public_Key_ECDSA; 80 Private_Key : in Private_Key_ECDSA; 81 SHA1_Hash : in W_Block160; 82 Signature : out Signature_ECDSA) is 83 temp_k : Big_Unsigned; 84 temp_EC: EC_Point; 85 temp_H : constant Big_Unsigned := To_Big_Unsigned(To_Bytes(Sha1_Hash)); 86 begin 87 loop 88 temp_k := Get_Random(Get_P(Public_Key.E) - Big_Unsigned_Three) + 89 Big_Unsigned_One; 90 91 temp_EC:= temp_k * Public_Key.P; 92 Signature.R := temp_EC.X mod Public_Key.n; 93 if Signature.R /= Big_Unsigned_Zero then 94 exit; 95 end if; 96 end loop; 97 98 Signature.S := Mult(Inverse(temp_k, Public_Key.n), 99 Add(temp_H, Mult(Private_Key.d, Signature.R, 100 Public_Key.n),Public_Key.n), 101 Public_Key.n); 102 end Sign; 103 104------------------------------------------------------------------------------- 105 106 function Verify(Public_Key : Public_Key_ECDSA; 107 SHA1_Hash : W_Block160; 108 Signature : Signature_ECDSA) return Boolean is 109 W : constant Big_Unsigned := Inverse(Signature.S, Public_Key.n); 110 U1 : constant Big_Unsigned := Mult(To_Big_Unsigned(To_Bytes(Sha1_Hash)), 111 W,Public_Key.n); 112 U2 : constant Big_Unsigned := Mult(Signature.R, W, Public_Key.n); 113 tmp_EC: constant EC_Point := (U1 * Public_Key.P) + (U2 * Public_Key.Q); 114 V : constant Big_Unsigned:= tmp_EC.x mod Get_P(Public_Key.E); 115 begin 116 if V = Signature.R then return True; 117 else return False; 118 end if; 119 end Verify; 120 121------------------------------------------------------------------------------- 122 123 procedure Sign_File(Filename : in String; 124 Public_Key : in Public_Key_ECDSA; 125 Private_Key : in Private_Key_ECDSA; 126 Signature : out Signature_ECDSA) is 127 begin 128 if Is_Init(ECDSA_S_Key(Private_Key)) and 129 Is_Init(ECDSA_P_Key(Public_Key)) then 130 Sign(Public_Key, Private_Key, SHA1.F_Hash(Filename), Signature); 131 else 132 raise Invalid_Private_Key_Error; 133 end if; 134 end Sign_File; 135 136------------------------------------------------------------------------------- 137 138 function Verify_File( 139 Filename : String; 140 Public_Key : Public_Key_ECDSA; 141 Signature : Signature_ECDSA) return Boolean is 142 begin 143 if Is_Init(ECDSA_P_Key(Public_Key)) then 144 return Verify(Public_Key, SHA1.F_Hash(Filename), Signature); 145 else 146 raise Invalid_Public_Key_Error; 147 end if; 148 end Verify_File; 149 150 151------------------------------------------------------------------------------- 152 153 function Verify_Key_Pair( 154 Private_Key : Private_Key_ECDSA; 155 Public_Key : Public_Key_ECDSA) return Boolean is 156 begin 157 if Is_Init(ECDSA_P_KEY(Public_Key)) = False or 158 Is_Init(ECDSA_S_KEY(Private_Key)) = False then 159 return False; 160 elsif 161 --- do some more? --- 162 (Private_Key.d * Public_Key.P = Public_Key.Q) and (Public_Key.Q = Private_Key.Q) then 163 return True; 164 else return False; 165 end if; 166 end Verify_Key_Pair; 167 168------------------------------------------------------------------------------- 169 170 function equal_Public_Key_Curve( 171 Public_Key_A : Public_Key_ECDSA; 172 Public_Key_B : Public_Key_ECDSA) return Boolean is 173 begin 174 if (Public_Key_A.E = Public_Key_B.E) and (Public_Key_A.P = Public_Key_B.P) and (Public_Key_A.n = Public_Key_B.n) then 175 return true; 176 else 177 return false; 178 end if; 179 end equal_Public_Key_Curve; 180 181------------------------------------------------------------------------------- 182 183end Crypto.Asymmetric.ECDSA; 184