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;