hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

types.ha (3189B)


      1 // SPDX-License-Identifier: MPL-2.0
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 use io;
      5 
      6 // Maxium coordinate size of the modules curves in bits.
      7 export def MAX_COORDBITSZ = 528z;
      8 
      9 // Maximum size of a point of the modules curves in bytes.
     10 export def MAX_POINTSZ = P521_POINTSZ;
     11 
     12 // Maximum size of a scalar of the modules curves in bytes.
     13 export def MAX_SCALARSZ = P521_SCALARSZ;
     14 
     15 // Interface for common operations over a specific curve.
     16 //
     17 // The encoding of points (e.g. public keys for dsa and dh) depends on the curve.
     18 // For the NIST curves ([[p256]], [[p384]] and [[p521]]) the point is required
     19 // to be stored according to the uncompressed format defined in RFC 8422 Chapter
     20 // 5.4.1. That means with a leading byte of value 0x04 that indicates the
     21 // format. Followed by the x and y coordinates, which must be of length
     22 // [[pointsz]] / 2, left padded by 0.
     23 //
     24 // Scalar values (e.g. private keys for dsa and dh) must be provided in
     25 // big-endian encoding and left-padded to fill the indicated space. They MUST be
     26 // non-zero and less than the curve order, otherwise result values will be
     27 // indeterminate and an error code is not guaranteed. The function [[scalarsz]]
     28 // will return the encoded scalar size of any curve implemented by this module.
     29 export type curve = struct {
     30 	// Size in bytes of an encoded point.
     31 	pointsz: size,
     32 
     33 	// Returns the order of the subgroup generated by the conventional
     34 	// generator. Unsigned big-endian encoding is used.
     35 	order: *fn () const []u8, // XXX: change to const []u8, when possible
     36 
     37 	// Get the conventional generator as an encoded curve point.
     38 	generator: *fn () const []u8, // XXX: change to const []u8, when possible
     39 
     40 	// Multiply curve point 'p' by scalar 'x'. The result is stored in 'r'.
     41 	// Returns 1 on success.
     42 	//
     43 	// Point 'p' must be a valid point on the curve subgroup. If this is
     44 	// not the case the function fails with 0 as result.
     45 	//
     46 	// On error the results in 'p' are indeterminate.
     47 	mul: *fn (p: []u8, x: []u8) u32,
     48 
     49 	// Multiply the generator by the scalar 'x' and write the result to 'r'.
     50 	//
     51 	// Returns the encoded point length in bytes.
     52 	mulgen: *fn (r: []u8, x: []u8) size,
     53 
     54 	// Multiply two curve points ('a' and 'b') by two integers ('x' and 'y')
     55 	// and stores the sum in 'a' ('a' = 'a' * 'x' + 'b' * 'y').
     56 	//
     57 	// If an empty slice is given as 'b', the curve generator is used
     58 	// instead of 'b'.
     59 	//
     60 	// Returns 0 in case of failure. Validates that the provided points are
     61 	// part of the relevant curve subgroup.
     62 	//
     63 	// Returns 1 on success.
     64 	muladd: *fn (a: []u8, b: []u8, x: []u8, y: []u8) u32,
     65 
     66 	// Generate a private key from given random seed 'rand'. The function
     67 	// may read repeatedly from 'rand' until a suitable key is found.
     68 	//
     69 	// Returns the size of bytes read into 'priv' on success or
     70 	// [[io::error]], if reading from 'rand' failed.
     71 	keygen: *fn (c: *curve, priv: []u8, rand: io::handle) (size | io::error),
     72 };
     73 
     74 // Returns the encoded size of any point of curve 'c'.
     75 export fn pointsz(c: *curve) size = c.pointsz;
     76 
     77 // Returns the encoded size of any scalar of curve 'c'.
     78 export fn scalarsz(c: *curve) size = len(c.order());
     79 
     80 // Invalid curve parameter.
     81 export type invalid = !void;