PureBasic
PureBasic
Create ECSDA Signature using Raw r and s Format (not ASN.1)
See more ECC Examples
Demonstrates how to create an ECDSA signature using the raw r/s format.ECDSA signatures have two equal sized parts, r and s. There are two common formats for encoding the signature:
(a) Concatenating the raw byte array of r and s
(b) Encoding both into a structured ASN.1 / DER sequence.
This example demonstrates how to create a signature that is a byte array of r and s concatenated.
Note: This example requires Chilkat v9.5.0.97 or greater.
Chilkat PureBasic Downloads
IncludeFile "CkStringBuilder.pb"
IncludeFile "CkPrivateKey.pb"
IncludeFile "CkPrng.pb"
IncludeFile "CkPublicKey.pb"
IncludeFile "CkEcc.pb"
Procedure ChilkatExample()
success.i = 0
; This example requires the Chilkat API to have been previously unlocked.
; See Global Unlock Sample for sample code.
; To create an ECDSA signature, the data first needs to be hashed. Then the hash
; is signed.
sb.i = CkStringBuilder::ckCreate()
If sb.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkStringBuilder::ckAppend(sb,"The quick brown fox jumps over the lazy dog")
hash.s = CkStringBuilder::ckGetHash(sb,"sha256","base64","utf-8")
; Load the ECDSA key to be used for signing.
privKey.i = CkPrivateKey::ckCreate()
If privKey.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkPrivateKey::ckLoadPemFile(privKey,"qa_data/ecc/secp256r1-key-pkcs8.pem")
If success <> 1
Debug CkPrivateKey::ckLastErrorText(privKey)
CkStringBuilder::ckDispose(sb)
CkPrivateKey::ckDispose(privKey)
ProcedureReturn
EndIf
prng.i = CkPrng::ckCreate()
If prng.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
ecdsa.i = CkEcc::ckCreate()
If ecdsa.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
; Produce a signature that is not ASN.1, but is instead the concatenation
; of the raw r and s signature parts.
; This feature was added in Chilkat v9.5.0.97
CkEcc::setCkAsnFormat(ecdsa, 0)
ecdsaSigBase64.s = CkEcc::ckSignHashENC(ecdsa,hash,"base64",privKey,prng)
If CkEcc::ckLastMethodSuccess(ecdsa) <> 1
Debug CkEcc::ckLastErrorText(ecdsa)
CkStringBuilder::ckDispose(sb)
CkPrivateKey::ckDispose(privKey)
CkPrng::ckDispose(prng)
CkEcc::ckDispose(ecdsa)
ProcedureReturn
EndIf
Debug "ECDSA signature = " + ecdsaSigBase64
; -----------------------------------------------------------
; Now let's verify the signature using the public key.
pubKey.i = CkPublicKey::ckCreate()
If pubKey.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkPublicKey::ckLoadFromFile(pubKey,"qa_data/ecc/secp256r1-pubkey.pem")
If success <> 1
Debug CkPublicKey::ckLastErrorText(pubKey)
CkStringBuilder::ckDispose(sb)
CkPrivateKey::ckDispose(privKey)
CkPrng::ckDispose(prng)
CkEcc::ckDispose(ecdsa)
CkPublicKey::ckDispose(pubKey)
ProcedureReturn
EndIf
; Note: When verifying, Chilkat will auto-detect the format for both kinds of ECDSA signatures (ASN.1 or binary r+s)
result.i = CkEcc::ckVerifyHashENC(ecdsa,hash,ecdsaSigBase64,"base64",pubKey)
If result = 1
Debug "Signature is valid."
CkStringBuilder::ckDispose(sb)
CkPrivateKey::ckDispose(privKey)
CkPrng::ckDispose(prng)
CkEcc::ckDispose(ecdsa)
CkPublicKey::ckDispose(pubKey)
ProcedureReturn
EndIf
If result = 0
Debug "Signature is invalid."
CkStringBuilder::ckDispose(sb)
CkPrivateKey::ckDispose(privKey)
CkPrng::ckDispose(prng)
CkEcc::ckDispose(ecdsa)
CkPublicKey::ckDispose(pubKey)
ProcedureReturn
EndIf
If result < 0
Debug CkEcc::ckLastErrorText(ecdsa)
Debug "The VerifyHashENC method call failed."
CkStringBuilder::ckDispose(sb)
CkPrivateKey::ckDispose(privKey)
CkPrng::ckDispose(prng)
CkEcc::ckDispose(ecdsa)
CkPublicKey::ckDispose(pubKey)
ProcedureReturn
EndIf
CkStringBuilder::ckDispose(sb)
CkPrivateKey::ckDispose(privKey)
CkPrng::ckDispose(prng)
CkEcc::ckDispose(ecdsa)
CkPublicKey::ckDispose(pubKey)
ProcedureReturn
EndProcedure