minssl
Software
www.skarnet.org

The kcdsa224 library interface

The kcdsa224 library implements digital signature generation and verification using EC-KCDSA on the NIST-approved P-224 elliptic curve. The KCDSA specification can be downloaded here.

Compiling

Linking

Programming

You should refer to the kcdsa224.h header for the exact function prototypes.

Basics

unsigned char const *p224_base ;

The "standard" base point on the P224 curve found by Dan Bernstein and used in nistp224 is available in p224_base. It is 56 bytes long; you can use the first 28 bytes if you just need a compressed point.
This point is used in the signature public key generation and in the signature verification. It is preferred over the base point given by the Digital Signature System standard because it works with the (undocumented) nistp224_uncompress() primitive, allowing use of compressed points and thus leading to 28-byte, instead of 56-byte, public keys.

kcdsa224 key generation

Let p224_q be the order of the P-224 elliptic curve. This number is explicited in several places, including the DSS reference.

unsigned char priv[28] ;
unsigned char pub[28] ;

 kcdsa224_keygen(pub, priv) ;
 kcdsa224_pubkey(pub, priv) ;

kcdsa224_pubkey() computes the public key pub associated to priv. pub is a compressed point on the P224 curve: namely, pub = (priv^(-1) mod p224_q).p224_base
kcdsa224_keygen() generates a public/private key pair. priv is randomly generated so that it represents a number between 1 and p224_q-1. pub is computed from priv by kcdsa224_pubkey().
These functions normally return 1; if there was a problem of any sort, they return 0.

Note that kcdsa224 interprets a private key e as 256^0*e[0] + 256^1*e[1] + ... + 256^27*e[27], whereas nistp224() interprets a private key e as 2^224 + 2^216(e[0]-136) + 2^208(e[1]-136) + ... + 2^0(e[27]-136).
The keys used by the minssl program suite are stored under the kcdsa224 format, not the nistp224 format.

The 28-byte hash function

unsigned char hash[28] ;
unsigned char sha[20] ;
unsigned char *cert ;
unsigned int certlen ;
unsigned char *msg ;
unsigned int msglen ;

 kcdsa224_hash(hash, cert, certlen, msg, msglen) ;
 kcdsa224_hashx(hash, sha) ;

kcdsa224_hash() concatenates cert of length certlen and msg of length msglen and hashes the result into hash.
kcdsa224_hashx() reads a 20-byte SHA-1 hash from sha and expands it to 28 bytes into hash. hash is actually made of the first 28 bytes of SHA1(sha ## "\000") ## SHA1(sha ## "\001"), where ## is the concatenation operator.

cert is (a hash value of) the certification data required by KCDSA. The KCDSA specification states: "[cert] should contain at least signer's distinguished identifier, public key y and the domain parameters p, q, g.". Since kcdsa224 only uses one domain, the P-224 elliptic curve with p = 2^224 - 2^96 + 1, q = p224_q and g = p224base, there is no need to include those in cert. For now, the minssl suite relies on the key manager system to check public keys against a local key database, so there is no need to include a distinguished identifier either: only the signer's public key needs to appear in cert. Some future release of minssl may include a complete public key infrastructure, including a certificate authority program. In that case, distinguished identifiers will be included in the certification data, and key managers will become unnecessary.

Signature

unsigned char sig[56] ;
unsigned char pub[28] ;
unsigned char priv[28] ;
unsigned char *msg ;
unsigned int msglen ;
unsigned char hash[28] ;
unsigned char kG[56] ;
unsigned char k[28] ;

 kcdsa224_sign(sig, pub, priv, msg, msglen) ;
 kcdsa224_signhash(sig, priv, hash) ;
 kcdsa224_signhashwith(sig, priv, hash, kG, k) ;

kcdsa224_sign() computes sig, a digital signature of msg of length msglen. The signature private key is priv and the signature public key is pub. pub is only used as certification data added to the message.
kcdsa224_signhash() signs a 28-byte hash with the private key priv. It assumes that the certification data has already been included in the hash.
kcdsa224_signhashwith() is an internal component of kcdsa224_signhash(). It uses a random secret k and its corresponding public part kG needed by the KCDSA algorithm. Be careful: kG is an uncompressed point on the P-224 curve, so it's 56 bytes long.
Those functions returns 1 in case of success, 0 in case of failure.

If you intend to use kcdsa224 outside of minssl, be careful that you must provide a way for the verifier to assert the validity of the signer's public key. If you're a certification authority and would like to certify public keys against identifiers, contact me so I can add hooks to include the identifiers in the KCDSA certification data.

Verification

unsigned char sig[56] ;
unsigned char pub[28] ;
unsigned char *msg ;
unsigned int msglen ;
unsigned char hash[28] ;
int res ;

 res = kcdsa224_verify(sig, pub, msg, len) ;
 res = kcdsa224_verifyhash(sig, pub, hash) ;

kcdsa224_verify() verifies that sig is a valid digital signature for the message msg of length msglen, with the public verification key pub.
kcdsa224_verifyhash() verifies that sig is a valid digital signature for the 28-byte hash hash.
Those functions return 1 if the signature is valid, 0 if it is not.