commit 5aaec08f83d401cbeea4a07fe15929af34a0c7f0
parent 02f24e201c8e7c49e959d77dba92fbc02248905a
Author: Drew DeVault <sir@cmpwn.com>
Date: Sat, 4 Sep 2021 08:07:59 +0200
crypto::*: use subtypes for hashes
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
11 files changed, 79 insertions(+), 109 deletions(-)
diff --git a/crypto/blake2b/+test.ha b/crypto/blake2b/+test.ha
@@ -14,20 +14,19 @@ use strio;
let in = hex::decode(vectors[i].in)!;
defer free(in);
let blake = blake2b(key, len(out));
- hash::write(blake, in);
+ hash::write(&blake, in);
let sum: []u8 = alloc([], len(out));
defer free(sum);
for (let i = 0z; i < len(out); i += 1) {
append(sum, 0);
};
- hash::finish(blake, sum);
+ hash::finish(&blake, sum);
let out = strio::dynamic();
hex::encode(out, sum)!;
assert(strio::string(out) == vectors[i].out);
};
let blake = blake2b([], 64);
- defer hash::close(blake);
const vectors = [
("", "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce"),
("abc", "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923"),
@@ -41,12 +40,12 @@ use strio;
for (let i = 0z; i < len(vectors); i += 1) {
const vector = vectors[i];
- hash::reset(blake);
- hash::write(blake, strings::toutf8(vector.0));
+ hash::reset(&blake);
+ hash::write(&blake, strings::toutf8(vector.0));
static let sum: [64]u8 = [0...];
- assert(len(sum) >= hash::sz(blake));
- hash::sum(blake, sum);
+ assert(len(sum) >= hash::sz(&blake));
+ hash::sum(&blake, sum);
let hex = strio::dynamic();
defer io::close(hex);
diff --git a/crypto/blake2b/blake2b.ha b/crypto/blake2b/blake2b.ha
@@ -32,7 +32,7 @@ const sigma: [12][16]u8 = [
[14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3],
];
-type digest = struct {
+export type digest = struct {
hash::hash,
h: [8]u64,
tlow: u64,
@@ -44,8 +44,10 @@ type digest = struct {
};
// Creates a [[hash::hash]] which computes a BLAKE2b hash with a given key and a
-// given hash size. The size must be between 1 and 64, inclusive.
-export fn blake2b(key: []u8, sz: size) *hash::hash = {
+// given hash size. The size must be between 1 and 64, inclusive. This hash
+// function does not allocate any additional state, so you do not need to call
+// [[hash::close]] when you are done with it.
+export fn blake2b(key: []u8, sz: size) digest = {
assert(1 <= sz);
assert(sz <= 64);
assert(len(key) <= 64);
@@ -53,9 +55,8 @@ export fn blake2b(key: []u8, sz: size) *hash::hash = {
h[0] ^= 0x01010000 ^ (len(key) << 8) ^ sz;
let keyblock: [BSIZE]u8 = [0...];
keyblock[..len(key)] = key;
- return alloc(digest {
+ return digest {
writer = &write,
- closer = &close,
sum = &sum,
reset = &reset,
sz = sz,
@@ -66,7 +67,8 @@ export fn blake2b(key: []u8, sz: size) *hash::hash = {
blocklen = if (len(key) > 0) BSIZE else 0,
key = keyblock,
keylen = len(key),
- }): *hash::hash;
+ ...
+ };
};
fn write(st: *io::stream, buf: const []u8) (size | io::error) = {
@@ -94,10 +96,6 @@ fn write(st: *io::stream, buf: const []u8) (size | io::error) = {
return length;
};
-fn close(st: *io::stream) void = {
- free(st);
-};
-
fn sum(h: *hash::hash, buf: []u8) void = {
let h = h: *digest;
let copy = *h;
diff --git a/crypto/md5/+test.ha b/crypto/md5/+test.ha
@@ -6,8 +6,6 @@ use io;
@test fn md5() void = {
let md5 = md5();
- defer hash::close(md5);
-
const vectors = [
("", "d41d8cd98f00b204e9800998ecf8427e"),
("abc", "900150983cd24fb0d6963f7d28e17f72"),
@@ -22,11 +20,11 @@ use io;
for (let i = 0z; i < len(vectors); i += 1) {
const vector = vectors[i];
- hash::reset(md5);
- hash::write(md5, strings::toutf8(vector.0));
+ hash::reset(&md5);
+ hash::write(&md5, strings::toutf8(vector.0));
let sum: [SIZE]u8 = [0...];
- hash::sum(md5, sum);
+ hash::sum(&md5, sum);
let hex = strio::dynamic();
defer io::close(hex);
diff --git a/crypto/md5/md5.ha b/crypto/md5/md5.ha
@@ -12,7 +12,7 @@ def init1: u32 = 0xEFCDAB89;
def init2: u32 = 0x98BADCFE;
def init3: u32 = 0x10325476;
-type digest = struct {
+export type digest = struct {
hash::hash,
h: [4]u32,
x: [chunk]u8,
@@ -24,16 +24,18 @@ type digest = struct {
// Note that MD5 is cryptographically broken and should not be used for secure
// applications. Where possible, applications are encouraged to use
// [[crypto::sha256]] or [[crypto::sha512]] instead.
-export fn md5() *hash::hash = {
- let md5 = alloc(digest {
+//
+// This hash function does not allocate any state, so you do not have to call
+// [[hash::close]] when you are done with it.
+export fn md5() digest = {
+ let md5 = digest {
writer = &write,
- closer = &close,
sum = &sum,
reset = &reset,
sz = SIZE,
...
- });
- hash::reset(md5);
+ };
+ hash::reset(&md5);
return md5;
};
@@ -69,8 +71,6 @@ fn write(st: *io::stream, buf: const []u8) (size | io::error) = {
return nn;
};
-fn close(st: *io::stream) void = free(st);
-
fn reset(h: *hash::hash) void = {
let h = h: *digest;
h.h[0] = init0;
diff --git a/crypto/sha1/+test.ha b/crypto/sha1/+test.ha
@@ -6,8 +6,6 @@ use io;
@test fn sha1() void = {
let sha = sha1();
- defer hash::close(sha);
-
const vectors = [
("", "da39a3ee5e6b4b0d3255bfef95601890afd80709"),
("abc", "a9993e364706816aba3e25717850c26c9cd0d89d"),
@@ -26,11 +24,11 @@ use io;
for (let i = 0z; i < len(vectors); i += 1) {
const vector = vectors[i];
- hash::reset(sha);
- hash::write(sha, strings::toutf8(vector.0));
+ hash::reset(&sha);
+ hash::write(&sha, strings::toutf8(vector.0));
let sum: [SIZE]u8 = [0...];
- hash::sum(sha, sum);
+ hash::sum(&sha, sum);
let hex = strio::dynamic();
defer io::close(hex);
@@ -52,12 +50,11 @@ use io;
// const expected = "7789f0c9ef7bfc40d93311143dfbe69e2017f592";
//
// let sha = sha1();
-// defer hash::finish(sha);
//
// for (let i = 0z; i < 16777216; i += 1)
-// hash::write(sha, strings::toutf8(input));
+// hash::write(&sha, strings::toutf8(input));
//
-// let sum = hash::sum(sha);
+// let sum = hash::sum(&sha);
// defer free(sum);
//
// let hex = strio::dynamic();
diff --git a/crypto/sha1/sha1.ha b/crypto/sha1/sha1.ha
@@ -15,7 +15,7 @@ def init2: u32 = 0x98BADCFE;
def init3: u32 = 0x10325476;
def init4: u32 = 0xC3D2E1F0;
-type digest = struct {
+export type digest = struct {
hash::hash,
h: [5]u32,
x: [chunk]u8,
@@ -26,16 +26,15 @@ type digest = struct {
// Creates a [[hash::hash]] which computes a SHA-1 hash. Note that this
// alogorithm is no longer considered secure. Where possible, applications are
// encouraged to use [[crypto::sha256]] or [[crypto::sha512]] instead.
-export fn sha1() *hash::hash = {
- let sha = alloc(digest {
+export fn sha1() digest = {
+ let sha = digest {
writer = &write,
- closer = &close,
sum = &sum,
reset = &reset,
sz = SIZE,
...
- });
- hash::reset(sha);
+ };
+ hash::reset(&sha);
return sha;
};
@@ -71,10 +70,6 @@ fn write(st: *io::stream, buf: const []u8) (size | io::error) = {
return nn;
};
-fn close(st: *io::stream) void = {
- free(st);
-};
-
fn reset(h: *hash::hash) void = {
let h = h: *digest;
h.h[0] = init0;
diff --git a/crypto/sha256/+test.ha b/crypto/sha256/+test.ha
@@ -6,8 +6,6 @@ use strio;
@test fn sha256() void = {
let sha = sha256();
- defer hash::close(sha);
-
const vectors = [
("", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"),
("abc", "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"),
@@ -23,11 +21,11 @@ use strio;
for (let i = 0z; i < len(vectors); i += 1) {
const vector = vectors[i];
- hash::reset(sha);
- hash::write(sha, strings::toutf8(vector.0));
+ hash::reset(&sha);
+ hash::write(&sha, strings::toutf8(vector.0));
let sum: [SIZE]u8 = [0...];
- hash::sum(sha, sum);
+ hash::sum(&sha, sum);
let hex = strio::dynamic();
defer io::close(hex);
@@ -46,11 +44,11 @@ use strio;
//const input = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno";
//const expected = "50e72a0e26442fe2552dc3938ac58658228c0cbfb1d2ca872ae435266fcd055e";
- //hash::reset(sha);
+ //hash::reset(&sha);
//for (let i = 0z; i < 16777216; i += 1) {
- // hash::write(sha, strings::toutf8(input));
+ // hash::write(&sha, strings::toutf8(input));
//};
- //let sum = hash::sum(sha);
+ //let sum = hash::sum(&sha);
//defer free(sum);
//let hex = strio::dynamic();
diff --git a/crypto/sha256/sha256.ha b/crypto/sha256/sha256.ha
@@ -31,7 +31,7 @@ const k: [_]u32 = [
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
];
-type state = struct {
+export type state = struct {
hash::hash,
h: [8]u32,
x: [chunk]u8,
@@ -40,16 +40,15 @@ type state = struct {
};
// Creates a [[hash::hash]] which computes a SHA-256 hash.
-export fn sha256() *hash::hash = {
- let sha = alloc(state {
+export fn sha256() state = {
+ let sha = state {
writer = &write,
- closer = &close,
sum = &sum,
reset = &reset,
sz = SIZE,
...
- });
- hash::reset(sha);
+ };
+ hash::reset(&sha);
return sha;
};
@@ -97,10 +96,6 @@ fn write(st: *io::stream, buf: const []u8) (size | io::error) = {
return n;
};
-fn close(st: *io::stream) void = {
- free(st);
-};
-
fn sum(h: *hash::hash, buf: []u8) void = {
let h = h: *state;
let copy = *h;
diff --git a/crypto/sha512/+test.ha b/crypto/sha512/+test.ha
@@ -6,8 +6,6 @@ use io;
@test fn sha512() void = {
let sha = sha512();
- defer hash::close(sha);
-
const vectors = [
("abc", "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"),
("", "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"),
@@ -22,11 +20,11 @@ use io;
for (let i = 0z; i < len(vectors); i += 1) {
const vector = vectors[i];
- hash::reset(sha);
- hash::write(sha, strings::toutf8(vector.0));
+ hash::reset(&sha);
+ hash::write(&sha, strings::toutf8(vector.0));
let sum: [SIZE]u8 = [0...];
- hash::sum(sha, sum);
+ hash::sum(&sha, sum);
let hex = strio::dynamic();
defer io::close(hex);
@@ -45,20 +43,19 @@ use io;
@test fn sha512_224() void = {
let sha = sha512_224();
- defer hash::close(sha);
-
const vectors = [
("", "6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4"),
("abc", "4634270f707b6a54daae7530460842e20e37ed265ceee9a43e8924aa"),
("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "23fec5bb94d60b23308192640b0c453335d664734fe40e7268674af9")
];
+
for (let i = 0z; i < len(vectors); i += 1) {
const vector = vectors[i];
- hash::reset(sha);
- hash::write(sha, strings::toutf8(vector.0));
+ hash::reset(&sha);
+ hash::write(&sha, strings::toutf8(vector.0));
let sum: [SIZE224]u8 = [0...];
- hash::sum(sha, sum);
+ hash::sum(&sha, sum);
let hex = strio::dynamic();
defer io::close(hex);
@@ -76,19 +73,19 @@ use io;
@test fn sha512_256() void = {
let sha = sha512_256();
- defer hash::close(sha);
const vectors = [
("", "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a"),
("abc", "53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23"),
("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "3928e184fb8690f840da3988121d31be65cb9d3ef83ee6146feac861e19b563a"),
];
+
for (let i = 0z; i < len(vectors); i += 1) {
const vector = vectors[i];
- hash::reset(sha);
- hash::write(sha, strings::toutf8(vector.0));
+ hash::reset(&sha);
+ hash::write(&sha, strings::toutf8(vector.0));
let sum: [SIZE256]u8 = [0...];
- hash::sum(sha, sum);
+ hash::sum(&sha, sum);
let hex = strio::dynamic();
defer io::close(hex);
@@ -108,19 +105,19 @@ use io;
@test fn sha384() void = {
let sha = sha384();
- defer hash::close(sha);
const vectors = [
("", "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b"),
("abc", "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7"),
("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039"),
];
+
for (let i = 0z; i < len(vectors); i += 1) {
const vector = vectors[i];
- hash::reset(sha);
- hash::write(sha, strings::toutf8(vector.0));
+ hash::reset(&sha);
+ hash::write(&sha, strings::toutf8(vector.0));
let sum: [SIZE384]u8 = [0...];
- hash::sum(sha, sum);
+ hash::sum(&sha, sum);
let hex = strio::dynamic();
defer io::close(hex);
diff --git a/crypto/sha512/sha512.ha b/crypto/sha512/sha512.ha
@@ -56,7 +56,7 @@ def init5_384: u64 = 0x8eb44a8768581511;
def init6_384: u64 = 0xdb0c2e0d64f98fa7;
def init7_384: u64 = 0x47b5481dbefa4fa4;
-type digest = struct {
+export type digest = struct {
hash::hash,
h: [8]u64,
x: [chunk]u8,
@@ -66,29 +66,28 @@ type digest = struct {
};
// Creates a [[hash::hash]] which computes a SHA-512 hash.
-export fn sha512() *hash::hash = init(variant::SHA512, SIZE);
+export fn sha512() digest = init(variant::SHA512, SIZE);
// Creates a [[hash::hash]] which computes a SHA-512/224 hash.
-export fn sha512_224() *hash::hash = init(variant::SHA512_224, SIZE224);
+export fn sha512_224() digest = init(variant::SHA512_224, SIZE224);
// Creates a [[hash::hash]] which computes a SHA-512/256 hash.
-export fn sha512_256() *hash::hash = init(variant::SHA512_256, SIZE256);
+export fn sha512_256() digest = init(variant::SHA512_256, SIZE256);
// Creates a [[hash::hash]] which computes a SHA-384 hash.
-export fn sha384() *hash::hash = init(variant::SHA384, SIZE384);
+export fn sha384() digest = init(variant::SHA384, SIZE384);
// Internal initialization function
-fn init(var: variant, sz: size) *hash::hash = {
- let sha = alloc(digest {
+fn init(var: variant, sz: size) digest = {
+ let sha = digest {
writer = &write,
- closer = &close,
sum = &sum,
reset = &reset,
sz = sz,
var = var,
- });
-
- hash::reset(sha);
+ ...
+ };
+ hash::reset(&sha);
return sha;
};
@@ -124,8 +123,6 @@ fn write(st: *io::stream, buf: const []u8) (size | io::error) = {
return nn;
};
-fn close(st: *io::stream) void = free(st);
-
fn sum(h: *hash::hash, buf: []u8) void = {
let d = h: *digest;
let copy = *d;
diff --git a/hare/module/scan.ha b/hare/module/scan.ha
@@ -20,7 +20,6 @@ use fmt;
export fn scan(ctx: *context, path: str) (version | error) = {
// TODO: Incorporate defines into the hash
let sha = sha256::sha256();
- defer hash::close(sha);
let found = false;
for (let i = 0z; i < len(ctx.tags); i += 1) {
if (ctx.tags[i].mode == tag_mode::INCLUSIVE
@@ -29,7 +28,7 @@ export fn scan(ctx: *context, path: str) (version | error) = {
break;
};
};
- hash::write(sha, [if (found) 1 else 0]);
+ hash::write(&sha, [if (found) 1 else 0]);
let iter = match (fs::iter(ctx.fs, path)) {
fs::wrongtype => {
// Single file case
@@ -50,8 +49,8 @@ export fn scan(ctx: *context, path: str) (version | error) = {
append(inputs, in);
let sumbuf: [sha256::SIZE]u8 = [0...];
- hash::write(sha, in.hash);
- hash::sum(sha, sumbuf);
+ hash::write(&sha, in.hash);
+ hash::sum(&sha, sumbuf);
return version {
hash = sumbuf,
@@ -67,13 +66,12 @@ export fn scan(ctx: *context, path: str) (version | error) = {
basedir = strings::dup(path),
...
};
- scan_directory(ctx, &ver, sha, path, iter)?;
+ scan_directory(ctx, &ver, &sha, path, iter)?;
let tmp: [sha256::SIZE]u8 = [0...];
- hash::sum(sha, tmp);
+ hash::sum(&sha, tmp);
ver.hash = alloc([], sha.sz);
append(ver.hash, tmp...);
-
return ver;
};
@@ -316,11 +314,9 @@ fn scan_file(
let f = fs::open(ctx.fs, path)?;
defer io::close(f);
let sha = sha256::sha256();
- defer hash::close(sha);
-
- hash::write(sha, strings::toutf8(path));
+ hash::write(&sha, strings::toutf8(path));
- let tee = io::tee(f, sha);
+ let tee = io::tee(f, &sha);
defer io::close(tee);
let lexer = lex::init(tee, path);
@@ -339,7 +335,7 @@ fn scan_file(
io::copy(io::empty, tee)?; // Finish spooling out the file for the SHA
let tmp: [sha256::SIZE]u8 = [0...];
- hash::sum(sha, tmp);
+ hash::sum(&sha, tmp);
let checksum: []u8 = alloc([], sha.sz);
append(checksum, tmp...);