minssl
Software
www.skarnet.org
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.
You should refer to the kcdsa224.h header for the exact function prototypes.
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.
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.
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.
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.
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.