YOUSEFUL / DELPHI / COMPONENTS
TAtlasEcdsa
ECDSA signatures on the NIST P-256 curve with SHA-256, and conversion of public keys to and from X/Y coordinates.
Description
Sign with the private key, verify with the public key. The data is hashed with SHA-256 inside Sign and Verify; pass the data itself, not a digest. Signatures are 64 bytes, r followed by s (the IEEE P1363 form CNG produces); DER-encoded signatures, as some libraries and certificate formats use, are not supported. ECDSA signatures are randomised, so signing the same data twice gives different signatures, both valid.
Verify returns False for a signature that does not match, but raises EAtlasCryptoError when the public key itself is unusable, so a configuration fault cannot look like a bad signature. The tests verify the published RFC 6979 appendix A.2.5 signature. ECDSA keys cannot be used with TAtlasEcdh, nor the other way round.
Members
| Member | Kind | What it does |
|---|---|---|
SignatureSize | field | The signature length in bytes: 32 for r, 32 for s. |
GenerateKeyPair | method | Returns a new P-256 key pair (72-byte public blob, 104-byte private blob). |
Sign | method | Returns the 64-byte signature of the SHA-256 digest of Data. |
Verify | method | True when Signature was made over Data by the private key matching PublicKey. |
PublicKeyFromXY | method | Builds a public key blob from the affine coordinates of a point, 32 bytes each, big-endian, as other systems publish them. |
PublicKeyToXY | method | Splits a P-256 ECDSA public key blob into its 32-byte X and Y coordinates. |
Methods
GenerateKeyPair method
class function GenerateKeyPair: TAtlasKeyPair; static;Returns a new P-256 key pair (72-byte public blob, 104-byte private blob).
Pair := TAtlasEcdsa.GenerateKeyPair;Sign method
class function Sign(const PrivateKey, Data: TBytes): TBytes; static;Returns the 64-byte signature of the SHA-256 digest of Data. Data may be empty. A blob that is not a P-256 ECDSA private key raises EAtlasCryptoError.
Signature := TAtlasEcdsa.Sign(Pair.PrivateKey, Data);Verify method
class function Verify(const PublicKey, Data, Signature: TBytes): Boolean; static;True when Signature was made over Data by the private key matching PublicKey. False for altered data, another key, an altered signature or a signature that is not 64 bytes. Raises EAtlasCryptoError when PublicKey is not a usable P-256 ECDSA public key.
Valid := TAtlasEcdsa.Verify(Pair.PublicKey, Data, Signature);PublicKeyFromXY method
class function PublicKeyFromXY(const X, Y: TBytes): TBytes; static;Builds a public key blob from the affine coordinates of a point, 32 bytes each, big-endian, as other systems publish them. The key is imported once to prove the point is on the curve; a point that is not, or coordinates of another length, raise EAtlasCryptoError.
Data := TAtlasEcdsa.PublicKeyFromXY(X, Y);PublicKeyToXY method
class procedure PublicKeyToXY(const PublicKey: TBytes; out X, Y: TBytes); static;Splits a P-256 ECDSA public key blob into its 32-byte X and Y coordinates. Anything else, an ECDH public key included, raises EAtlasCryptoError (Not a P-256 ECDSA public key).
TAtlasEcdsa.PublicKeyToXY(Pair.PublicKey, X, Y);Fields
SignatureSize field
const SignatureSize = 64;The signature length in bytes: 32 for r, 32 for s.
Examples
Verify a signature published by another implementation
RFC 6979 appendix A.2.5 gives a P-256 public key as coordinates and a SHA-256 signature of sample. Prints TRUE, then FALSE for a different message.
uses System.SysUtils, Atlas.Crypto, Atlas.CryptoKeys;
procedure VerifyPublishedSignature;
var
PublicKey, Signature: TBytes;
begin
PublicKey := TAtlasEcdsa.PublicKeyFromXY(
TAtlasBytes.FromHex('60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6'),
TAtlasBytes.FromHex('7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299'));
Signature := TAtlasBytes.FromHex('EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716' +
'F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8');
WriteLn(TAtlasEcdsa.Verify(PublicKey, TAtlasBytes.OfString('sample'), Signature));
WriteLn(TAtlasEcdsa.Verify(PublicKey, TAtlasBytes.OfString('Sample'), Signature));
end;
Sign a file and publish the public key as coordinates
Signs the bytes of a file and prints the public key as two 64-digit hexadecimal numbers that anyone can use to rebuild it with PublicKeyFromXY. Prints the coordinates and TRUE.
uses System.SysUtils, System.IOUtils, Atlas.Crypto, Atlas.CryptoKeys;
procedure SignAFile;
var
Pair: TAtlasKeyPair;
FileName: string;
Signature, X, Y: TBytes;
begin
FileName := TPath.Combine(TPath.GetTempPath, 'atlas-crypto-release.txt');
TFile.WriteAllBytes(FileName, TAtlasBytes.OfString('release 4.2'));
Pair := TAtlasEcdsa.GenerateKeyPair;
try
Signature := TAtlasEcdsa.Sign(Pair.PrivateKey, TFile.ReadAllBytes(FileName));
TAtlasEcdsa.PublicKeyToXY(Pair.PublicKey, X, Y);
WriteLn('X = ', TAtlasBytes.ToHex(X));
WriteLn('Y = ', TAtlasBytes.ToHex(Y));
WriteLn(TAtlasEcdsa.Verify(TAtlasEcdsa.PublicKeyFromXY(X, Y), TFile.ReadAllBytes(FileName), Signature));
finally
Pair.Wipe;
TFile.Delete(FileName);
end;
end;
Related
TAtlasKeyPair · TAtlasEcdh · TAtlasRsa