commit 804e55f74e20b15fc2d46d6c5de89b0da829e035
parent 13c16e6a44e8d94308cb10880f73f0627270aec3
Author: Armin Preiml <apreiml@strohwolke.at>
Date: Sun, 27 Aug 2023 21:02:58 +0200
crypto::*25519: change api to take slices
see commit 83fcdf51
Diffstat:
3 files changed, 50 insertions(+), 17 deletions(-)
diff --git a/crypto/curve25519/curve25519.ha b/crypto/curve25519/curve25519.ha
@@ -30,36 +30,50 @@ const _121665: elem = [0xdb41, 1, 0...];
// Compute the result of the scalar multiplication (scalar * point) and put the
// result in out.
export fn x25519(
- out: *[SCALARSZ]u8,
- scalar: const *[SCALARSZ]u8,
- point: const *[POINTSZ]u8
+ out: []u8,
+ scalar: const []u8,
+ point: const []u8,
) void = {
+ assert(len(out) == SCALARSZ);
+ assert(len(scalar) == SCALARSZ);
+ assert(len(point) == POINTSZ);
+
scalarmult(out, scalar, point);
};
// Compute the result of the scalar multiplication (scalar * point) where point
// is BASEPOINT.
export fn scalarmult_base(
- out: *[SCALARSZ]u8,
- scalar: const *[SCALARSZ]u8
+ out: []u8,
+ scalar: const []u8
) void = {
+ assert(len(out) == SCALARSZ);
+ assert(len(scalar) == SCALARSZ);
+
scalarmult(out, scalar, &BASEPOINT);
};
// Prepares the scalar to avoid particular attacks. See the "clamping" section
// in Kleppmann's paper.
-export fn clamp(scalar: *[SCALARSZ]u8) void = {
+export fn clamp(scalar: []u8) void = {
+ assert(len(scalar) == SCALARSZ);
scalar[0] &= 0xf8;
scalar[31] = (scalar[31] & 0x7f) | 0x40;
};
// Set out to the product (scalar * point)
export fn scalarmult(
- out: *[SCALARSZ]u8,
- scalar: const *[SCALARSZ]u8,
- point: const *[POINTSZ]u8
+ out: []u8,
+ scalar: const []u8,
+ point: const []u8
) void = {
- let clamped: [SCALARSZ]u8 = *scalar;
+ assert(len(out) == SCALARSZ);
+ assert(len(scalar) == SCALARSZ);
+ assert(len(point) == POINTSZ);
+
+ let clamped: [SCALARSZ]u8 = [0...];
+ clamped[..] = scalar[..];
+
defer bytes::zero(clamped);
clamp(&clamped);
@@ -103,7 +117,7 @@ export fn scalarmult(
pack25519(out, &a);
};
-fn unpack25519(in: *[SCALARSZ]u8) elem = {
+fn unpack25519(in: []u8) elem = {
let fe: elem = [0...];
for (let i = 0z; i < FIELDSZ; i += 1) {
@@ -188,7 +202,7 @@ fn swap25519(p: *elem, q: *elem, bit: i64) void = {
};
};
-fn pack25519(out: *[SCALARSZ]u8, a: const *elem) void = {
+fn pack25519(out: []u8, a: const *elem) void = {
let m: elem = [0...];
let t: elem = *a;
diff --git a/crypto/ed25519/ed25519.ha b/crypto/ed25519/ed25519.ha
@@ -28,8 +28,10 @@ export type seed = [SEEDSZ]u8;
// Derives a new Ed25519 private key from a given seed. The seed must be
// initialized to cryptographically random data; [[crypto::random]] is
// recommended for this purpose.
-export fn privkey_init(priv: []u8, seed: *seed) void = {
+export fn privkey_init(priv: []u8, seed: []u8) void = {
assert(len(priv) == PRIVKEYSZ);
+ assert(len(seed) == SEEDSZ);
+
let h: [64]u8 = [0...];
let sha = sha512::sha512();
hash::write(&sha, seed[..]);
diff --git a/crypto/x25519/x25519.ha b/crypto/x25519/x25519.ha
@@ -3,23 +3,40 @@
use crypto::curve25519;
// Type for private, public or shared keys.
-export type key = [32]u8;
+export type key = [KEYSZ]u8;
+
+// The size of a x25519 key.
+export def KEYSZ: size = 32;
+
+// The size of a x25519 key seed.
+export def SEEDSZ: size = 32;
// Initializes a new x25519 private key from the provided 32-byte seed,
// which should be generated with [[crypto::random]].
-export fn newkey(priv: *key, seed: *[32]u8) void = {
+export fn newkey(priv: []u8, seed: []u8) void = {
+ assert(len(priv) == KEYSZ);
+ assert(len(seed) == SEEDSZ);
+
priv[..] = seed[..];
curve25519::clamp(priv);
};
// Derives the public key from a private key prepared with [[newkey]],
// writing it to the 'pub' parameter.
-export fn pubkey(pub: *key, priv: const *key) void =
+export fn pubkey(pub: []u8, priv: const []u8) void = {
+ assert(len(priv) == KEYSZ);
+ assert(len(pub) == KEYSZ);
+
curve25519::scalarmult_base(pub, priv);
+};
// Derives a 32-byte shared key from the private key of one key-pair and
// the public key of a second key-pair.
-export fn derive(shared: *key, priv: *key, pub: *key) void = {
+export fn derive(shared: []u8, priv: []u8, pub: []u8) void = {
+ assert(len(shared) == KEYSZ);
+ assert(len(priv) == KEYSZ);
+ assert(len(pub) == KEYSZ);
+
curve25519::x25519(shared, priv, pub);
// TODO figure out if checking for low order points is required