crypto::ec
The crypto::ec module provides implementations for a selection of elliptic curves and their operations.
This is a low-level module which implements cryptographic primitives. Direct use of cryptographic primitives is not recommended for non-experts, as incorrect use of these primitives can easily lead to the introduction of security vulnerabilities. Non-experts are advised to use the high-level operations available in the top-level crypto:: module.
Be advised that Hare's cryptography implementations have not been audited.
Index
Types
type curve = struct {
pointsz: size,
order: *fn() const []u8,
generator: *fn() const []u8,
mul: *fn(p: []u8, x: []u8) u32,
mulgen: *fn(r: []u8, x: []u8) size,
muladd: *fn(a: []u8, b: []u8, x: []u8, y: []u8) u32,
keygen: *fn(c: *curve, priv: []u8, rand: io::handle) (size | io::error),
};
Errors
type invalid = !void;
Constants
def MAX_COORDBITSZ = 528z;
def MAX_POINTSZ = P521_POINTSZ;
def MAX_SCALARSZ = P521_SCALARSZ;
def P256_POINTSZ = 65;
def P256_SCALARSZ = 32;
def P384_POINTSZ = 97;
def P384_SCALARSZ = 48;
def P521_POINTSZ = 133;
def P521_SCALARSZ = 66;
Globals
const p256: *curve;
const p384: *curve;
const p521: *curve;
Functions
fn keygen(c: *curve, priv: []u8, rand: io::handle) (size | io::error);
fn pointsz(c: *curve) size;
fn scalarsz(c: *curve) size;
fn validate_point(c: *curve, p: []u8) (void | invalid);
fn validate_pointformat(c: *curve, p: []u8) (void | invalid);
fn validate_scalar(c: *curve, n: []u8) (void | invalid);
Types
type curve
type curve = struct {
pointsz: size,
order: *fn() const []u8,
generator: *fn() const []u8,
mul: *fn(p: []u8, x: []u8) u32,
mulgen: *fn(r: []u8, x: []u8) size,
muladd: *fn(a: []u8, b: []u8, x: []u8, y: []u8) u32,
keygen: *fn(c: *curve, priv: []u8, rand: io::handle) (size | io::error),
};
Interface for common operations over a specific curve.
The encoding of points (e.g. public keys for dsa and dh) depends on the curve. For the NIST curves (p256, p384 and p521) the point is required to be stored according to the uncompressed format defined in RFC 8422 Chapter 5.4.1. That means with a leading byte of value 0x04 that indicates the format. Followed by the x and y coordinates, which must be of length pointsz / 2, left padded by 0.
Scalar values (e.g. private keys for dsa and dh) must be provided in big-endian encoding and left-padded to fill the indicated space. They MUST be non-zero and less than the curve order, otherwise result values will be indeterminate and an error code is not guaranteed. The function scalarsz will return the encoded scalar size of any curve implemented by this module.
Errors
type invalid
type invalid = !void;
Invalid curve parameter.
Constants
def MAX_COORDBITSZ
def MAX_COORDBITSZ = 528z;
Maxium coordinate size of the modules curves in bits.
def MAX_POINTSZ
def MAX_POINTSZ = P521_POINTSZ;
Maximum size of a point of the modules curves in bytes.
def MAX_SCALARSZ
def MAX_SCALARSZ = P521_SCALARSZ;
Maximum size of a scalar of the modules curves in bytes.
def P256_POINTSZ
def P256_POINTSZ = 65;
Size of a p256 point in bytes.
def P256_SCALARSZ
def P256_SCALARSZ = 32;
Size of a p256 scalar in bytes.
def P384_POINTSZ
def P384_POINTSZ = 97;
Size of a p384 point in bytes.
def P384_SCALARSZ
def P384_SCALARSZ = 48;
Size of a p384 scalar in bytes.
def P521_POINTSZ
def P521_POINTSZ = 133;
Size of a p521 point in bytes.
def P521_SCALARSZ
def P521_SCALARSZ = 66;
Size of a p521 scalar in bytes.
Globals
let p256
const p256: *curve;
Can't parse docs: /home/build/hare/crypto/ec/p256.ha:1258:27: syntax error: Unterminated reference
let p384
const p384: *curve;
Can't parse docs: /home/build/hare/crypto/ec/prime.ha:711:27: syntax error: Unterminated reference
let p521
const p521: *curve;
Can't parse docs: /home/build/hare/crypto/ec/prime.ha:777:27: syntax error: Unterminated reference
Functions
fn keygen
fn keygen(c: *curve, priv: []u8, rand: io::handle) (size | io::error);
Generates a random private key scalar suitable for given curve 'c'. 'rand' must be cryptographic random stream like the one provided by crypto::random::stream.
fn pointsz
fn pointsz(c: *curve) size;
Returns the encoded size of any point of curve 'c'.
fn scalarsz
fn scalarsz(c: *curve) size;
Returns the encoded size of any scalar of curve 'c'.
fn validate_point
fn validate_point(c: *curve, p: []u8) (void | invalid);
Checks if given point is properly encoded and a valid point on given curve 'c'. This operation is quite expensive. Note that in any case point validation will be done on every mul and muladd operation.
fn validate_pointformat(c: *curve, p: []u8) (void | invalid);
Checks whether the point is encoded in the curves point format. Does NOT check if it is a valid point on the curve. For such point validation use validate_point.
fn validate_scalar
fn validate_scalar(c: *curve, n: []u8) (void | invalid);
Validates if given scalar is less than the curve order and greater then zero.