D. J. Bernstein

Authenticators and signatures

nistp224
# The nistp224 library interface

The nistp224 library is in `/package/math/nistp224/library/nistp224.a`.
## Compressed point multiplication

#include "/package/math/nistp224/include/nistp224.h"
int nistp224(*xe*,*x*,*e*);
unsigned char *e*[28];
unsigned char *x*[28];
unsigned char *xe*[28];

`nistp224` reads an integer *e*
and a compressed point *x*.
It produces another compressed point *xe*.
The integer *e* is
2^224
+ 2^216(*e*[0] - 136)
+ 2^208(*e*[1] - 136)
+ ...
+ 2^0(*e*[27] - 136).

The compressed point *x* is
2^0 *x*[0]
+ 2^8 *x*[1]
+ ...
+ 2^216 *x*[27].
Normally *x* is a compressed point on the NIST P-224 elliptic curve;
this means that

*x* is between 0 and 2^224-2^96 inclusive and
*x*^3 - 3*x* + *b*
is a square modulo the prime 2^224-2^96+1.

Here *b* is the integer with hexadecimal representation
b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4.
Normally
`nistp224` sets *xe* to a compressed point on the curve,
namely the *e*th multiple
of *x* on the curve,
and returns 1.
If *x* is not a compressed point on the curve,
or if *e* is exactly the order of the curve,
`nistp224` clears *xe* and returns 0.

## Compressed Diffie-Hellman

`nistp224` can be used for compressed Diffie-Hellman key exchange
on the NIST P-224 elliptic curve,
with 28-byte public keys.
To generate a public key:
Put 28 secret random bytes into *e* to form your secret key.
Put the 28-byte compressed standard base point

"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"

into *x*.
Call `nistp224`.
The output *xe* will be your 28-byte public key.
(It is theoretically possible, though astronomically unlikely,
that your secret *e* will be exactly the order of the curve,
in which case `nistp224` will return 0.
You can eliminate this possibility in advance,
with essentially no loss in security,
by choosing *e*[0] between 8 and 135 inclusive.)

To compute a shared secret:
Put your secret key into *e*.
Put someone else's 28-byte public key into *x*.
Call `nistp224`.
The output *xe* will be your shared secret.

## Uncompressed point multiplication

#include "/package/math/nistp224/include/nistp224.h"
int nistp224_56(*xye*,*xy*,*e*);
unsigned char *e*[28];
unsigned char *xy*[56];
unsigned char *xye*[56];

`nistp224` reads an integer *e*
and a point *xy*.
It produces another point *xye*.
The integer *e* is
2^224
+ 2^216(*e*[0] - 136)
+ 2^208(*e*[1] - 136)
+ ...
+ 2^0(*e*[27] - 136).

The point *xy* has two pieces:
*x* is
2^0 *xy*[0]
+ 2^8 *xy*[1]
+ ...
+ 2^216 *xy*[27],
and
*y* is
2^0 *xy*[28]
+ 2^8 *xy*[29]
+ ...
+ 2^216 *xy*[55].
Normally (*x*,*y*) is
a point on the NIST P-224 elliptic curve;
this means that

*x* and *y* are between 0 and 2^224-2^96 inclusive and
*y*^2 - *x*^3 + 3*x* - *b*
is divisible by the prime 2^224-2^96+1.

Here *b* is the integer with hexadecimal representation
b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4.
Normally
`nistp224_56` sets *xye* to a point on the curve,
namely the *e*th multiple
of *xy* on the curve,
and returns 1.
If *xy* is not a point on the curve,
or if *e* is exactly the order of the curve,
`nistp224_56` clears *xye* and returns 0.

## Uncompressed Diffie-Hellman

`nistp224_56` can be used for uncompressed Diffie-Hellman key exchange
on the NIST P-224 elliptic curve,
with 56-byte public keys.
To generate a public key:
Put 28 secret random bytes into *e* to form your secret key.
Put the 56-byte standard base point

"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
"1\r\037\257\021\276\331\332\336\324\376\353\024s"
"\235\270enr\320\334\316b0,\361\216\223"

into *xy*.
Call `nistp224_56`.
The output *xye* will be your 56-byte public key.
To compute a shared secret:
Put your secret key into *e*.
Put someone else's 56-byte public key into *xy*.
Call `nistp224_56`.
The output *xye* will be your shared secret.