Browse Source

Update UCrypto.pas -> TRawBytes

PascalCoin 6 years ago
parent
commit
db38ee4c2c
1 changed files with 47 additions and 53 deletions
  1. 47 53
      src/core/UCrypto.pas

+ 47 - 53
src/core/UCrypto.pas

@@ -44,7 +44,7 @@ Type
     Property PrivateKey : PEC_KEY read FPrivateKey;
     Property PrivateKey : PEC_KEY read FPrivateKey;
     Property PublicKey : TECDSA_Public read GetPublicKey;
     Property PublicKey : TECDSA_Public read GetPublicKey;
     Property PublicKeyPoint : PEC_POINT read GetPublicKeyPoint;
     Property PublicKeyPoint : PEC_POINT read GetPublicKeyPoint;
-    Function SetPrivateKeyFromHexa(EC_OpenSSL_NID : Word; hexa : AnsiString) : Boolean;
+    Function SetPrivateKeyFromHexa(EC_OpenSSL_NID : Word; const hexa : AnsiString) : Boolean;
     Property EC_OpenSSL_NID : Word Read FEC_OpenSSL_NID;
     Property EC_OpenSSL_NID : Word Read FEC_OpenSSL_NID;
     class function IsValidPublicKey(PubKey : TECDSA_Public) : Boolean;
     class function IsValidPublicKey(PubKey : TECDSA_Public) : Boolean;
     Function ExportToRaw : TRawBytes;
     Function ExportToRaw : TRawBytes;
@@ -57,24 +57,24 @@ Type
   private
   private
   public
   public
     class function IsHexString(const AHexString: AnsiString) : boolean;
     class function IsHexString(const AHexString: AnsiString) : boolean;
-    class function ToHexaString(const raw : TRawBytes) : AnsiString;
+    class function ToHexaString(const raw : TRawBytes) : AnsiString; // DEPRECATED: Use TRawBytes.ToHexaString instead
     class function HexaToRaw(const HexaString : AnsiString) : TRawBytes; overload;
     class function HexaToRaw(const HexaString : AnsiString) : TRawBytes; overload;
     class function HexaToRaw(const HexaString : AnsiString; out raw : TRawBytes) : Boolean; overload;
     class function HexaToRaw(const HexaString : AnsiString; out raw : TRawBytes) : Boolean; overload;
     class function DoSha256(p : PAnsiChar; plength : Cardinal) : TRawBytes; overload;
     class function DoSha256(p : PAnsiChar; plength : Cardinal) : TRawBytes; overload;
-    class function DoSha256(const TheMessage : AnsiString) : TRawBytes; overload;
-    class procedure DoSha256(const TheMessage : AnsiString; out ResultSha256 : TRawBytes);  overload;
-    class function DoDoubleSha256(const TheMessage : AnsiString) : TRawBytes; overload;
+    class function DoSha256(const TheMessage : TRawBytes) : TRawBytes; overload;
+    class procedure DoSha256(const TheMessage : TRawBytes; out ResultSha256 : TRawBytes);  overload;
+    class function DoDoubleSha256(const TheMessage : TRawBytes) : TRawBytes; overload;
     class procedure DoDoubleSha256(p : PAnsiChar; plength : Cardinal; out ResultSha256 : TRawBytes); overload;
     class procedure DoDoubleSha256(p : PAnsiChar; plength : Cardinal; out ResultSha256 : TRawBytes); overload;
-    class function DoRandomHash(const TheMessage : AnsiString) : TRawBytes; overload;
+    class function DoRandomHash(const TheMessage : TRawBytes) : TRawBytes; overload;
     class procedure DoRandomHash(p : PAnsiChar; plength : Cardinal; out ResultSha256 : TRawBytes); overload;
     class procedure DoRandomHash(p : PAnsiChar; plength : Cardinal; out ResultSha256 : TRawBytes); overload;
     class procedure DoRandomHash(AFastHasher : TRandomHashFast; p : PAnsiChar; plength : Cardinal; out ResultSha256 : TRawBytes); overload;
     class procedure DoRandomHash(AFastHasher : TRandomHashFast; p : PAnsiChar; plength : Cardinal; out ResultSha256 : TRawBytes); overload;
-    class function DoRipeMD160_HEXASTRING(const TheMessage : AnsiString) : TRawBytes; overload;
+    class function DoRipeMD160_HEXASTRING(const TheMessage : TRawBytes) : TRawBytes; overload;
     class function DoRipeMD160AsRaw(p : PAnsiChar; plength : Cardinal) : TRawBytes; overload;
     class function DoRipeMD160AsRaw(p : PAnsiChar; plength : Cardinal) : TRawBytes; overload;
-    class function DoRipeMD160AsRaw(const TheMessage : AnsiString) : TRawBytes; overload;
+    class function DoRipeMD160AsRaw(const TheMessage : TRawBytes) : TRawBytes; overload;
     class function PrivateKey2Hexa(Key : PEC_KEY) : AnsiString;
     class function PrivateKey2Hexa(Key : PEC_KEY) : AnsiString;
-    class function ECDSASign(Key : PEC_KEY; const digest : AnsiString) : TECDSA_SIG;
-    class function ECDSAVerify(EC_OpenSSL_NID : Word; PubKey : EC_POINT; const digest : AnsiString; Signature : TECDSA_SIG) : Boolean; overload;
-    class function ECDSAVerify(PubKey : TECDSA_Public; const digest : AnsiString; Signature : TECDSA_SIG) : Boolean; overload;
+    class function ECDSASign(Key : PEC_KEY; const digest : TRawBytes) : TECDSA_SIG;
+    class function ECDSAVerify(EC_OpenSSL_NID : Word; PubKey : EC_POINT; const digest : TRawBytes; Signature : TECDSA_SIG) : Boolean; overload;
+    class function ECDSAVerify(PubKey : TECDSA_Public; const digest : TRawBytes; Signature : TECDSA_SIG) : Boolean; overload;
     class procedure InitCrypto;
     class procedure InitCrypto;
     class function IsHumanReadable(Const ReadableText : TRawBytes) : Boolean;
     class function IsHumanReadable(Const ReadableText : TRawBytes) : Boolean;
     class function EncodeSignature(const signature : TECDSA_SIG) : TRawBytes;
     class function EncodeSignature(const signature : TECDSA_SIG) : TRawBytes;
@@ -122,8 +122,8 @@ Type
   End;
   End;
 
 
 Const
 Const
-  CT_TECDSA_Public_Nul : TECDSA_Public = (EC_OpenSSL_NID:0;x:'';y:'');
-  CT_TECDSA_SIG_Nul : TECDSA_SIG = (r:'';s:'');
+  CT_TECDSA_Public_Nul : TECDSA_Public = (EC_OpenSSL_NID:0;x:Nil;y:Nil);
+  CT_TECDSA_SIG_Nul : TECDSA_SIG = (r:Nil;s:Nil);
 
 
 implementation
 implementation
 
 
@@ -314,7 +314,7 @@ begin
   FPrivateKey := Value;
   FPrivateKey := Value;
 end;
 end;
 
 
-function TECPrivateKey.SetPrivateKeyFromHexa(EC_OpenSSL_NID : Word; hexa : AnsiString) : Boolean;
+function TECPrivateKey.SetPrivateKeyFromHexa(EC_OpenSSL_NID : Word; const hexa : AnsiString) : Boolean;
 var bn : PBIGNUM;
 var bn : PBIGNUM;
   ctx : PBN_CTX;
   ctx : PBN_CTX;
   pub_key : PEC_POINT;
   pub_key : PEC_POINT;
@@ -322,7 +322,7 @@ begin
   Result := False;
   Result := False;
   bn := BN_new;
   bn := BN_new;
   try
   try
-    if BN_hex2bn(@bn,PAnsiChar(hexa))=0 then Raise ECryptoException.Create('Invalid Hexadecimal value:'+TCrypto.ToHexaString(hexa));
+    if BN_hex2bn(@bn,PAnsiChar(hexa))=0 then Raise ECryptoException.Create('Invalid hexa string to convert to Hexadecimal value');
 
 
     if Assigned(FPrivateKey) then EC_KEY_free(FPrivateKey);
     if Assigned(FPrivateKey) then EC_KEY_free(FPrivateKey);
     FEC_OpenSSL_NID := EC_OpenSSL_NID;
     FEC_OpenSSL_NID := EC_OpenSSL_NID;
@@ -360,25 +360,27 @@ begin
   SHA256(PS,32,PS);
   SHA256(PS,32,PS);
 end;
 end;
 
 
-class function TCrypto.DoDoubleSha256(const TheMessage: AnsiString): TRawBytes;
+class function TCrypto.DoDoubleSha256(const TheMessage: TRawBytes): TRawBytes;
 begin
 begin
   Result := DoSha256(DoSha256(TheMessage));
   Result := DoSha256(DoSha256(TheMessage));
 end;
 end;
 
 
-class function TCrypto.DoRipeMD160_HEXASTRING(const TheMessage: AnsiString): TRawBytes;
+class function TCrypto.DoRipeMD160_HEXASTRING(const TheMessage: TRawBytes): TRawBytes;
 Var PS : PAnsiChar;
 Var PS : PAnsiChar;
   PC : PAnsiChar;
   PC : PAnsiChar;
   i : Integer;
   i : Integer;
+  tmp : String;
 begin
 begin
   GetMem(PS,33);
   GetMem(PS,33);
-  RIPEMD160(PAnsiChar(TheMessage),Length(TheMessage),PS);
+  RIPEMD160(PAnsiChar(@TheMessage[Low(TheMessage)]),Length(TheMessage),PS);
   PC := PS;
   PC := PS;
-  Result := '';
-  for I := 1 to 20 do begin
-    Result := Result + IntToHex(PtrInt(PC^),2);
+  tmp := '';
+  for i := 1 to 20 do begin
+    tmp := tmp + IntToHex(PtrInt(PC^),2);
     inc(PC);
     inc(PC);
   end;
   end;
   FreeMem(PS,33);
   FreeMem(PS,33);
+  Result := TEncoding.ASCII.GetBytes(tmp);
 end;
 end;
 
 
 class function TCrypto.DoRipeMD160AsRaw(p: PAnsiChar; plength: Cardinal): TRawBytes;
 class function TCrypto.DoRipeMD160AsRaw(p: PAnsiChar; plength: Cardinal): TRawBytes;
@@ -389,12 +391,12 @@ begin
   RIPEMD160(p,plength,PS);
   RIPEMD160(p,plength,PS);
 end;
 end;
 
 
-class function TCrypto.DoRipeMD160AsRaw(const TheMessage: AnsiString): TRawBytes;
+class function TCrypto.DoRipeMD160AsRaw(const TheMessage: TRawBytes): TRawBytes;
 Var PS : PAnsiChar;
 Var PS : PAnsiChar;
 begin
 begin
   SetLength(Result,20);
   SetLength(Result,20);
   PS := @Result[Low(Result)];
   PS := @Result[Low(Result)];
-  RIPEMD160(PAnsiChar(TheMessage),Length(TheMessage),PS);
+  RIPEMD160(PAnsiChar(@TheMessage[Low(TheMessage)]),Length(TheMessage),PS);
 end;
 end;
 
 
 class function TCrypto.DoSha256(p: PAnsiChar; plength: Cardinal): TRawBytes;
 class function TCrypto.DoSha256(p: PAnsiChar; plength: Cardinal): TRawBytes;
@@ -405,32 +407,32 @@ begin
   SHA256(p,plength,PS);
   SHA256(p,plength,PS);
 end;
 end;
 
 
-class function TCrypto.DoSha256(const TheMessage: AnsiString): TRawBytes;
+class function TCrypto.DoSha256(const TheMessage: TRawBytes): TRawBytes;
 Var PS : PAnsiChar;
 Var PS : PAnsiChar;
 begin
 begin
   SetLength(Result,32);
   SetLength(Result,32);
   PS := @Result[Low(Result)];
   PS := @Result[Low(Result)];
-  SHA256(PAnsiChar(TheMessage),Length(TheMessage),PS);
+  SHA256(@TheMessage[Low(TheMessage)],Length(TheMessage),PS);
 end;
 end;
 
 
 { New at Build 2.1.6
 { New at Build 2.1.6
   Note: Delphi is slowly when working with Strings (allowing space)... so to
   Note: Delphi is slowly when working with Strings (allowing space)... so to
   increase speed we use a String as a pointer, and only increase speed if
   increase speed we use a String as a pointer, and only increase speed if
   needed. Also the same with functions "GetMem" and "FreeMem" }
   needed. Also the same with functions "GetMem" and "FreeMem" }
-class procedure TCrypto.DoSha256(const TheMessage: AnsiString; out ResultSha256: TRawBytes);
+class procedure TCrypto.DoSha256(const TheMessage: TRawBytes; out ResultSha256: TRawBytes);
 Var PS : PAnsiChar;
 Var PS : PAnsiChar;
 begin
 begin
   If length(ResultSha256)<>32 then SetLength(ResultSha256,32);
   If length(ResultSha256)<>32 then SetLength(ResultSha256,32);
   PS := @ResultSha256[Low(ResultSha256)];
   PS := @ResultSha256[Low(ResultSha256)];
-  SHA256(PAnsiChar(TheMessage),Length(TheMessage),PS);
+  SHA256(@TheMessage[Low(TheMessage)],Length(TheMessage),PS);
 end;
 end;
 
 
-class function TCrypto.ECDSASign(Key: PEC_KEY; const digest: AnsiString): TECDSA_SIG;
+class function TCrypto.ECDSASign(Key: PEC_KEY; const digest: TRawBytes): TECDSA_SIG;
 Var PECS : PECDSA_SIG;
 Var PECS : PECDSA_SIG;
   p : PAnsiChar;
   p : PAnsiChar;
   i : Integer;
   i : Integer;
 begin
 begin
-  PECS := ECDSA_do_sign(PAnsiChar(digest),length(digest),Key);
+  PECS := ECDSA_do_sign(PAnsiChar(@digest[Low(digest)]),Length(digest),Key);
   Try
   Try
     if PECS = Nil then raise ECryptoException.Create('Error signing');
     if PECS = Nil then raise ECryptoException.Create('Error signing');
 
 
@@ -448,7 +450,7 @@ begin
   End;
   End;
 end;
 end;
 
 
-class function TCrypto.ECDSAVerify(EC_OpenSSL_NID : Word; PubKey: EC_POINT; const digest: AnsiString; Signature: TECDSA_SIG): Boolean;
+class function TCrypto.ECDSAVerify(EC_OpenSSL_NID : Word; PubKey: EC_POINT; const digest: TRawBytes; Signature: TECDSA_SIG): Boolean;
 Var PECS : PECDSA_SIG;
 Var PECS : PECDSA_SIG;
   PK : PEC_KEY;
   PK : PEC_KEY;
   {$IFDEF OpenSSL10}
   {$IFDEF OpenSSL10}
@@ -472,7 +474,7 @@ begin
 
 
     PK := EC_KEY_new_by_curve_name(EC_OpenSSL_NID);
     PK := EC_KEY_new_by_curve_name(EC_OpenSSL_NID);
     EC_KEY_set_public_key(PK,@PubKey);
     EC_KEY_set_public_key(PK,@PubKey);
-    Case ECDSA_do_verify(PAnsiChar(digest),length(digest),PECS,PK) of
+    Case ECDSA_do_verify(@digest[Low(digest)],Length(digest),PECS,PK) of
       1 : Result := true;
       1 : Result := true;
       0 : Result := false;
       0 : Result := false;
     Else
     Else
@@ -484,7 +486,7 @@ begin
   End;
   End;
 end;
 end;
 
 
-class function TCrypto.ECDSAVerify(PubKey: TECDSA_Public; const digest: AnsiString; Signature: TECDSA_SIG): Boolean;
+class function TCrypto.ECDSAVerify(PubKey: TECDSA_Public; const digest: TRawBytes; Signature: TECDSA_SIG): Boolean;
 Var BNx,BNy : PBIGNUM;
 Var BNx,BNy : PBIGNUM;
   ECG : PEC_GROUP;
   ECG : PEC_GROUP;
   ctx : PBN_CTX;
   ctx : PBN_CTX;
@@ -518,15 +520,15 @@ Var P : PAnsiChar;
  lc : AnsiString;
  lc : AnsiString;
  i : Integer;
  i : Integer;
 begin
 begin
-  Result := '';
+  SetLength(Result,0);
   if ((Length(HexaString) MOD 2)<>0) Or (Length(HexaString)=0) then exit;
   if ((Length(HexaString) MOD 2)<>0) Or (Length(HexaString)=0) then exit;
-  SetLength(result,Length(HexaString) DIV 2);
+  SetLength(Result,Length(HexaString) DIV 2);
   P := @Result[Low(Result)];
   P := @Result[Low(Result)];
   lc := LowerCase(HexaString);
   lc := LowerCase(HexaString);
   i := HexToBin(PAnsiChar(@lc[Low(lc)]),P,Length(Result));
   i := HexToBin(PAnsiChar(@lc[Low(lc)]),P,Length(Result));
   if (i<>(Length(HexaString) DIV 2)) then begin
   if (i<>(Length(HexaString) DIV 2)) then begin
     TLog.NewLog(lterror,Classname,'Invalid HEXADECIMAL string result '+inttostr(i)+'<>'+inttostr(Length(HexaString) DIV 2)+': '+HexaString);
     TLog.NewLog(lterror,Classname,'Invalid HEXADECIMAL string result '+inttostr(i)+'<>'+inttostr(Length(HexaString) DIV 2)+': '+HexaString);
-    Result := '';
+    SetLength(Result,0);
   end;
   end;
 end;
 end;
 
 
@@ -535,7 +537,8 @@ Var P : PAnsiChar;
  lc : AnsiString;
  lc : AnsiString;
  i : Integer;
  i : Integer;
 begin
 begin
-  Result := False; raw := '';
+  Result := False;
+  SetLength(raw,0);
   if ((Length(HexaString) MOD 2)<>0) then Exit;
   if ((Length(HexaString) MOD 2)<>0) then Exit;
   if (Length(HexaString)=0) then begin
   if (Length(HexaString)=0) then begin
     Result := True;
     Result := True;
@@ -554,11 +557,12 @@ begin
 end;
 end;
 
 
 class function TCrypto.IsHumanReadable(const ReadableText: TRawBytes): Boolean;
 class function TCrypto.IsHumanReadable(const ReadableText: TRawBytes): Boolean;
+  // Will return TRUE if all bytes are between 32..126 (ASCII printable bytes)
 Var i : Integer;
 Var i : Integer;
 Begin
 Begin
   Result := true;
   Result := true;
-  for i := 1 to length(ReadableText) do begin
-    if (ord(ReadableText[i])<32) Or (ord(ReadableText[i])>=255) then begin
+  for i := Low(ReadableText) to High(ReadableText) do begin
+    if (ord(ReadableText[i])<32) Or (ord(ReadableText[i])>=127) then begin
       Result := false;
       Result := false;
       Exit;
       Exit;
     end;
     end;
@@ -600,23 +604,13 @@ class function TCrypto.PrivateKey2Hexa(Key: PEC_KEY): AnsiString;
 Var p : PAnsiChar;
 Var p : PAnsiChar;
 begin
 begin
   p := BN_bn2hex(EC_KEY_get0_private_key(Key));
   p := BN_bn2hex(EC_KEY_get0_private_key(Key));
-//  p := BN_bn2hex(Key^.priv_key);
   Result := strpas(p);
   Result := strpas(p);
   OPENSSL_free(p);
   OPENSSL_free(p);
 end;
 end;
 
 
 class function TCrypto.ToHexaString(const raw: TRawBytes): AnsiString;
 class function TCrypto.ToHexaString(const raw: TRawBytes): AnsiString;
-Var i : Integer;
-  s : AnsiString;
-  b : Byte;
-begin
-  SetLength(Result,length(raw)*2);
-  for i := 0 to length(raw)-1 do begin
-    b := Ord(raw[i+1]);
-    s := IntToHex(b,2);
-    Result[(i*2)+1] := s[1];
-    Result[(i*2)+2] := s[2];
-  end;
+begin
+  Result := raw.ToHexaString;
 end;
 end;
 
 
 class function TCrypto.IsHexString(const AHexString: AnsiString) : boolean;
 class function TCrypto.IsHexString(const AHexString: AnsiString) : boolean;
@@ -624,7 +618,7 @@ var
   i : Integer;
   i : Integer;
 begin
 begin
   Result := true;
   Result := true;
-  for i := 1 to length(AHexString) do
+  for i := Low(AHexString) to High(AHexString) do
     if (NOT (AHexString[i] in ['0'..'9'])) AND
     if (NOT (AHexString[i] in ['0'..'9'])) AND
        (NOT (AHexString[i] in ['a'..'f'])) AND
        (NOT (AHexString[i] in ['a'..'f'])) AND
        (NOT (AHexString[i] in ['A'..'F'])) then begin
        (NOT (AHexString[i] in ['A'..'F'])) then begin
@@ -635,9 +629,9 @@ end;
 
 
 { New at Build 4.0.0 }
 { New at Build 4.0.0 }
 
 
-class function TCrypto.DoRandomHash(const TheMessage: AnsiString): TRawBytes;
+class function TCrypto.DoRandomHash(const TheMessage: TRawBytes): TRawBytes;
 begin
 begin
-  DoRandomHash(PAnsiChar(TheMessage),Length(TheMessage),Result);
+  Result := TRandomHashFast.Compute(TheMessage);
 end;
 end;
 
 
 class procedure TCrypto.DoRandomHash(p : PAnsiChar; plength : Cardinal; out ResultSha256 : TRawBytes);
 class procedure TCrypto.DoRandomHash(p : PAnsiChar; plength : Cardinal; out ResultSha256 : TRawBytes);