mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Merge branch 'master' into freestanding_amd64
This commit is contained in:
@@ -0,0 +1,336 @@
|
|||||||
|
package siphash
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2022 zhibog
|
||||||
|
Made available under the BSD-3 license.
|
||||||
|
|
||||||
|
List of contributors:
|
||||||
|
zhibog: Initial implementation.
|
||||||
|
|
||||||
|
Implementation of the SipHash hashing algorithm, as defined at <https://github.com/veorq/SipHash> and <https://www.aumasson.jp/siphash/siphash.pdf>
|
||||||
|
|
||||||
|
Use the specific procedures for a certain setup. The generic procdedures will default to Siphash 2-4
|
||||||
|
*/
|
||||||
|
|
||||||
|
import "core:crypto"
|
||||||
|
import "core:crypto/util"
|
||||||
|
import "core:mem"
|
||||||
|
|
||||||
|
/*
|
||||||
|
High level API
|
||||||
|
*/
|
||||||
|
|
||||||
|
KEY_SIZE :: 16
|
||||||
|
DIGEST_SIZE :: 8
|
||||||
|
|
||||||
|
// sum_string_1_3 will hash the given message with the key and return
|
||||||
|
// the computed hash as a u64
|
||||||
|
sum_string_1_3 :: proc(msg, key: string) -> u64 {
|
||||||
|
return sum_bytes_1_3(transmute([]byte)(msg), transmute([]byte)(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_bytes_1_3 will hash the given message with the key and return
|
||||||
|
// the computed hash as a u64
|
||||||
|
sum_bytes_1_3 :: proc (msg, key: []byte) -> u64 {
|
||||||
|
ctx: Context
|
||||||
|
hash: u64
|
||||||
|
init(&ctx, key, 1, 3)
|
||||||
|
update(&ctx, msg)
|
||||||
|
final(&ctx, &hash)
|
||||||
|
return hash
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_string_to_buffer_1_3 will hash the given message with the key and write
|
||||||
|
// the computed hash into the provided destination buffer
|
||||||
|
sum_string_to_buffer_1_3 :: proc(msg, key: string, dst: []byte) {
|
||||||
|
sum_bytes_to_buffer_1_3(transmute([]byte)(msg), transmute([]byte)(key), dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_bytes_to_buffer_1_3 will hash the given message with the key and write
|
||||||
|
// the computed hash into the provided destination buffer
|
||||||
|
sum_bytes_to_buffer_1_3 :: proc(msg, key, dst: []byte) {
|
||||||
|
assert(len(dst) >= DIGEST_SIZE, "crypto/siphash: Destination buffer needs to be at least of size 8")
|
||||||
|
hash := sum_bytes_1_3(msg, key)
|
||||||
|
_collect_output(dst[:], hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
sum_1_3 :: proc {
|
||||||
|
sum_string_1_3,
|
||||||
|
sum_bytes_1_3,
|
||||||
|
sum_string_to_buffer_1_3,
|
||||||
|
sum_bytes_to_buffer_1_3,
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify_u64_1_3 will check if the supplied tag matches with the output you
|
||||||
|
// will get from the provided message and key
|
||||||
|
verify_u64_1_3 :: proc (tag: u64 msg, key: []byte) -> bool {
|
||||||
|
return sum_bytes_1_3(msg, key) == tag
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify_bytes will check if the supplied tag matches with the output you
|
||||||
|
// will get from the provided message and key
|
||||||
|
verify_bytes_1_3 :: proc (tag, msg, key: []byte) -> bool {
|
||||||
|
derived_tag: [8]byte
|
||||||
|
sum_bytes_to_buffer_1_3(msg, key, derived_tag[:])
|
||||||
|
return crypto.compare_constant_time(derived_tag[:], tag) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
verify_1_3 :: proc {
|
||||||
|
verify_bytes_1_3,
|
||||||
|
verify_u64_1_3,
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_string_2_4 will hash the given message with the key and return
|
||||||
|
// the computed hash as a u64
|
||||||
|
sum_string_2_4 :: proc(msg, key: string) -> u64 {
|
||||||
|
return sum_bytes_2_4(transmute([]byte)(msg), transmute([]byte)(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_bytes_2_4 will hash the given message with the key and return
|
||||||
|
// the computed hash as a u64
|
||||||
|
sum_bytes_2_4 :: proc (msg, key: []byte) -> u64 {
|
||||||
|
ctx: Context
|
||||||
|
hash: u64
|
||||||
|
init(&ctx, key, 2, 4)
|
||||||
|
update(&ctx, msg)
|
||||||
|
final(&ctx, &hash)
|
||||||
|
return hash
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_string_to_buffer_2_4 will hash the given message with the key and write
|
||||||
|
// the computed hash into the provided destination buffer
|
||||||
|
sum_string_to_buffer_2_4 :: proc(msg, key: string, dst: []byte) {
|
||||||
|
sum_bytes_to_buffer_2_4(transmute([]byte)(msg), transmute([]byte)(key), dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_bytes_to_buffer_2_4 will hash the given message with the key and write
|
||||||
|
// the computed hash into the provided destination buffer
|
||||||
|
sum_bytes_to_buffer_2_4 :: proc(msg, key, dst: []byte) {
|
||||||
|
assert(len(dst) >= DIGEST_SIZE, "crypto/siphash: Destination buffer needs to be at least of size 8")
|
||||||
|
hash := sum_bytes_2_4(msg, key)
|
||||||
|
_collect_output(dst[:], hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
sum_2_4 :: proc {
|
||||||
|
sum_string_2_4,
|
||||||
|
sum_bytes_2_4,
|
||||||
|
sum_string_to_buffer_2_4,
|
||||||
|
sum_bytes_to_buffer_2_4,
|
||||||
|
}
|
||||||
|
|
||||||
|
sum_string :: sum_string_2_4
|
||||||
|
sum_bytes :: sum_bytes_2_4
|
||||||
|
sum_string_to_buffer :: sum_string_to_buffer_2_4
|
||||||
|
sum_bytes_to_buffer :: sum_bytes_to_buffer_2_4
|
||||||
|
sum :: proc {
|
||||||
|
sum_string,
|
||||||
|
sum_bytes,
|
||||||
|
sum_string_to_buffer,
|
||||||
|
sum_bytes_to_buffer,
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify_u64_2_4 will check if the supplied tag matches with the output you
|
||||||
|
// will get from the provided message and key
|
||||||
|
verify_u64_2_4 :: proc (tag: u64 msg, key: []byte) -> bool {
|
||||||
|
return sum_bytes_2_4(msg, key) == tag
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify_bytes will check if the supplied tag matches with the output you
|
||||||
|
// will get from the provided message and key
|
||||||
|
verify_bytes_2_4 :: proc (tag, msg, key: []byte) -> bool {
|
||||||
|
derived_tag: [8]byte
|
||||||
|
sum_bytes_to_buffer_2_4(msg, key, derived_tag[:])
|
||||||
|
return crypto.compare_constant_time(derived_tag[:], tag) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
verify_2_4 :: proc {
|
||||||
|
verify_bytes_2_4,
|
||||||
|
verify_u64_2_4,
|
||||||
|
}
|
||||||
|
|
||||||
|
verify_bytes :: verify_bytes_2_4
|
||||||
|
verify_u64 :: verify_u64_2_4
|
||||||
|
verify :: proc {
|
||||||
|
verify_bytes,
|
||||||
|
verify_u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_string_4_8 will hash the given message with the key and return
|
||||||
|
// the computed hash as a u64
|
||||||
|
sum_string_4_8 :: proc(msg, key: string) -> u64 {
|
||||||
|
return sum_bytes_4_8(transmute([]byte)(msg), transmute([]byte)(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_bytes_4_8 will hash the given message with the key and return
|
||||||
|
// the computed hash as a u64
|
||||||
|
sum_bytes_4_8 :: proc (msg, key: []byte) -> u64 {
|
||||||
|
ctx: Context
|
||||||
|
hash: u64
|
||||||
|
init(&ctx, key, 4, 8)
|
||||||
|
update(&ctx, msg)
|
||||||
|
final(&ctx, &hash)
|
||||||
|
return hash
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_string_to_buffer_4_8 will hash the given message with the key and write
|
||||||
|
// the computed hash into the provided destination buffer
|
||||||
|
sum_string_to_buffer_4_8 :: proc(msg, key: string, dst: []byte) {
|
||||||
|
sum_bytes_to_buffer_4_8(transmute([]byte)(msg), transmute([]byte)(key), dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_bytes_to_buffer_4_8 will hash the given message with the key and write
|
||||||
|
// the computed hash into the provided destination buffer
|
||||||
|
sum_bytes_to_buffer_4_8 :: proc(msg, key, dst: []byte) {
|
||||||
|
assert(len(dst) >= DIGEST_SIZE, "crypto/siphash: Destination buffer needs to be at least of size 8")
|
||||||
|
hash := sum_bytes_4_8(msg, key)
|
||||||
|
_collect_output(dst[:], hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
sum_4_8 :: proc {
|
||||||
|
sum_string_4_8,
|
||||||
|
sum_bytes_4_8,
|
||||||
|
sum_string_to_buffer_4_8,
|
||||||
|
sum_bytes_to_buffer_4_8,
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify_u64_4_8 will check if the supplied tag matches with the output you
|
||||||
|
// will get from the provided message and key
|
||||||
|
verify_u64_4_8 :: proc (tag: u64 msg, key: []byte) -> bool {
|
||||||
|
return sum_bytes_4_8(msg, key) == tag
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify_bytes will check if the supplied tag matches with the output you
|
||||||
|
// will get from the provided message and key
|
||||||
|
verify_bytes_4_8 :: proc (tag, msg, key: []byte) -> bool {
|
||||||
|
derived_tag: [8]byte
|
||||||
|
sum_bytes_to_buffer_4_8(msg, key, derived_tag[:])
|
||||||
|
return crypto.compare_constant_time(derived_tag[:], tag) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
verify_4_8 :: proc {
|
||||||
|
verify_bytes_4_8,
|
||||||
|
verify_u64_4_8,
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Low level API
|
||||||
|
*/
|
||||||
|
|
||||||
|
init :: proc(ctx: ^Context, key: []byte, c_rounds, d_rounds: int) {
|
||||||
|
assert(len(key) == KEY_SIZE, "crypto/siphash: Invalid key size, want 16")
|
||||||
|
ctx.c_rounds = c_rounds
|
||||||
|
ctx.d_rounds = d_rounds
|
||||||
|
is_valid_setting := (ctx.c_rounds == 1 && ctx.d_rounds == 3) ||
|
||||||
|
(ctx.c_rounds == 2 && ctx.d_rounds == 4) ||
|
||||||
|
(ctx.c_rounds == 4 && ctx.d_rounds == 8)
|
||||||
|
assert(is_valid_setting, "crypto/siphash: Incorrect rounds set up. Valid pairs are (1,3), (2,4) and (4,8)")
|
||||||
|
ctx.k0 = util.U64_LE(key[:8])
|
||||||
|
ctx.k1 = util.U64_LE(key[8:])
|
||||||
|
ctx.v0 = 0x736f6d6570736575 ~ ctx.k0
|
||||||
|
ctx.v1 = 0x646f72616e646f6d ~ ctx.k1
|
||||||
|
ctx.v2 = 0x6c7967656e657261 ~ ctx.k0
|
||||||
|
ctx.v3 = 0x7465646279746573 ~ ctx.k1
|
||||||
|
ctx.is_initialized = true
|
||||||
|
}
|
||||||
|
|
||||||
|
update :: proc(ctx: ^Context, data: []byte) {
|
||||||
|
assert(ctx.is_initialized, "crypto/siphash: Context is not initalized")
|
||||||
|
ctx.last_block = len(data) / 8 * 8
|
||||||
|
ctx.buf = data
|
||||||
|
i := 0
|
||||||
|
m: u64
|
||||||
|
for i < ctx.last_block {
|
||||||
|
m = u64(ctx.buf[i] & 0xff)
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
for r in u64(1)..<8 {
|
||||||
|
m |= u64(ctx.buf[i] & 0xff) << (r * 8)
|
||||||
|
i += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.v3 ~= m
|
||||||
|
for _ in 0..<ctx.c_rounds {
|
||||||
|
_compress(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.v0 ~= m
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final :: proc(ctx: ^Context, dst: ^u64) {
|
||||||
|
m: u64
|
||||||
|
for i := len(ctx.buf) - 1; i >= ctx.last_block; i -= 1 {
|
||||||
|
m <<= 8
|
||||||
|
m |= u64(ctx.buf[i] & 0xff)
|
||||||
|
}
|
||||||
|
m |= u64(len(ctx.buf) << 56)
|
||||||
|
|
||||||
|
ctx.v3 ~= m
|
||||||
|
|
||||||
|
for _ in 0..<ctx.c_rounds {
|
||||||
|
_compress(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.v0 ~= m
|
||||||
|
ctx.v2 ~= 0xff
|
||||||
|
|
||||||
|
for _ in 0..<ctx.d_rounds {
|
||||||
|
_compress(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
dst^ = ctx.v0 ~ ctx.v1 ~ ctx.v2 ~ ctx.v3
|
||||||
|
|
||||||
|
reset(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
reset :: proc(ctx: ^Context) {
|
||||||
|
ctx.k0, ctx.k1 = 0, 0
|
||||||
|
ctx.v0, ctx.v1 = 0, 0
|
||||||
|
ctx.v2, ctx.v3 = 0, 0
|
||||||
|
ctx.last_block = 0
|
||||||
|
ctx.c_rounds = 0
|
||||||
|
ctx.d_rounds = 0
|
||||||
|
ctx.is_initialized = false
|
||||||
|
}
|
||||||
|
|
||||||
|
Context :: struct {
|
||||||
|
v0, v1, v2, v3: u64, // State values
|
||||||
|
k0, k1: u64, // Split key
|
||||||
|
c_rounds: int, // Number of message rounds
|
||||||
|
d_rounds: int, // Number of finalization rounds
|
||||||
|
buf: []byte, // Provided data
|
||||||
|
last_block: int, // Offset from the last block
|
||||||
|
is_initialized: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
_get_byte :: #force_inline proc "contextless" (byte_num: byte, into: u64) -> byte {
|
||||||
|
return byte(into >> (((~byte_num) & (size_of(u64) - 1)) << 3))
|
||||||
|
}
|
||||||
|
|
||||||
|
_collect_output :: #force_inline proc "contextless" (dst: []byte, hash: u64) {
|
||||||
|
dst[0] = _get_byte(7, hash)
|
||||||
|
dst[1] = _get_byte(6, hash)
|
||||||
|
dst[2] = _get_byte(5, hash)
|
||||||
|
dst[3] = _get_byte(4, hash)
|
||||||
|
dst[4] = _get_byte(3, hash)
|
||||||
|
dst[5] = _get_byte(2, hash)
|
||||||
|
dst[6] = _get_byte(1, hash)
|
||||||
|
dst[7] = _get_byte(0, hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
_compress :: #force_inline proc "contextless" (ctx: ^Context) {
|
||||||
|
ctx.v0 += ctx.v1
|
||||||
|
ctx.v1 = util.ROTL64(ctx.v1, 13)
|
||||||
|
ctx.v1 ~= ctx.v0
|
||||||
|
ctx.v0 = util.ROTL64(ctx.v0, 32)
|
||||||
|
ctx.v2 += ctx.v3
|
||||||
|
ctx.v3 = util.ROTL64(ctx.v3, 16)
|
||||||
|
ctx.v3 ~= ctx.v2
|
||||||
|
ctx.v0 += ctx.v3
|
||||||
|
ctx.v3 = util.ROTL64(ctx.v3, 21)
|
||||||
|
ctx.v3 ~= ctx.v0
|
||||||
|
ctx.v2 += ctx.v1
|
||||||
|
ctx.v1 = util.ROTL64(ctx.v1, 17)
|
||||||
|
ctx.v1 ~= ctx.v2
|
||||||
|
ctx.v2 = util.ROTL64(ctx.v2, 32)
|
||||||
|
}
|
||||||
+203
-211
File diff suppressed because it is too large
Load Diff
@@ -334,11 +334,11 @@ is_relative_slice :: proc(info: ^Type_Info) -> bool {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
write_typeid_builder :: proc(buf: ^strings.Builder, id: typeid) {
|
write_typeid_builder :: proc(buf: ^strings.Builder, id: typeid, n_written: ^int = nil) -> (n: int, err: io.Error) {
|
||||||
write_type(buf, type_info_of(id))
|
return write_type_writer(strings.to_writer(buf), type_info_of(id))
|
||||||
}
|
}
|
||||||
write_typeid_writer :: proc(writer: io.Writer, id: typeid) {
|
write_typeid_writer :: proc(writer: io.Writer, id: typeid, n_written: ^int = nil) -> (n: int, err: io.Error) {
|
||||||
write_type(writer, type_info_of(id))
|
return write_type_writer(writer, type_info_of(id), n_written)
|
||||||
}
|
}
|
||||||
|
|
||||||
write_typeid :: proc{
|
write_typeid :: proc{
|
||||||
|
|||||||
+2
-2
@@ -473,11 +473,11 @@ void print_bug_report_help() {
|
|||||||
|
|
||||||
#elif defined(GB_SYSTEM_LINUX)
|
#elif defined(GB_SYSTEM_LINUX)
|
||||||
/*
|
/*
|
||||||
Try to parse `/usr/lib/os-release` for `PRETTY_NAME="Ubuntu 20.04.3 LTS`
|
Try to parse `/etc/os-release` for `PRETTY_NAME="Ubuntu 20.04.3 LTS`
|
||||||
*/
|
*/
|
||||||
gbAllocator a = heap_allocator();
|
gbAllocator a = heap_allocator();
|
||||||
|
|
||||||
gbFileContents release = gb_file_read_contents(a, 1, "/usr/lib/os-release");
|
gbFileContents release = gb_file_read_contents(a, 1, "/etc/os-release");
|
||||||
defer (gb_file_free_contents(&release));
|
defer (gb_file_free_contents(&release));
|
||||||
|
|
||||||
b32 found = 0;
|
b32 found = 0;
|
||||||
|
|||||||
+63
-1
@@ -132,6 +132,62 @@ void check_did_you_mean_print(DidYouMeanAnswers *d, char const *prefix = "") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void populate_check_did_you_mean_objc_entity(StringSet *set, Entity *e, bool is_type) {
|
||||||
|
if (e->kind != Entity_TypeName) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (e->TypeName.objc_metadata == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TypeNameObjCMetadata *objc_metadata = e->TypeName.objc_metadata;
|
||||||
|
Type *t = base_type(e->type);
|
||||||
|
GB_ASSERT(t->kind == Type_Struct);
|
||||||
|
|
||||||
|
if (is_type) {
|
||||||
|
for_array(i, objc_metadata->type_entries) {
|
||||||
|
String name = objc_metadata->type_entries[i].name;
|
||||||
|
string_set_add(set, name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for_array(i, objc_metadata->value_entries) {
|
||||||
|
String name = objc_metadata->value_entries[i].name;
|
||||||
|
string_set_add(set, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for_array(i, t->Struct.fields) {
|
||||||
|
Entity *f = t->Struct.fields[i];
|
||||||
|
if (f->flags & EntityFlag_Using && f->type != nullptr) {
|
||||||
|
if (f->type->kind == Type_Named && f->type->Named.type_name) {
|
||||||
|
populate_check_did_you_mean_objc_entity(set, f->type->Named.type_name, is_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void check_did_you_mean_objc_entity(String const &name, Entity *e, bool is_type, char const *prefix = "") {
|
||||||
|
ERROR_BLOCK();
|
||||||
|
GB_ASSERT(e->kind == Entity_TypeName);
|
||||||
|
GB_ASSERT(e->TypeName.objc_metadata != nullptr);
|
||||||
|
auto *objc_metadata = e->TypeName.objc_metadata;
|
||||||
|
mutex_lock(objc_metadata->mutex);
|
||||||
|
defer (mutex_unlock(objc_metadata->mutex));
|
||||||
|
|
||||||
|
StringSet set = {};
|
||||||
|
string_set_init(&set, heap_allocator());
|
||||||
|
defer (string_set_destroy(&set));
|
||||||
|
populate_check_did_you_mean_objc_entity(&set, e, is_type);
|
||||||
|
|
||||||
|
|
||||||
|
DidYouMeanAnswers d = did_you_mean_make(heap_allocator(), set.entries.count, name);
|
||||||
|
defer (did_you_mean_destroy(&d));
|
||||||
|
for_array(i, set.entries) {
|
||||||
|
did_you_mean_append(&d, set.entries[i].value);
|
||||||
|
}
|
||||||
|
check_did_you_mean_print(&d, prefix);
|
||||||
|
}
|
||||||
|
|
||||||
void check_did_you_mean_type(String const &name, Array<Entity *> const &fields, char const *prefix = "") {
|
void check_did_you_mean_type(String const &name, Array<Entity *> const &fields, char const *prefix = "") {
|
||||||
ERROR_BLOCK();
|
ERROR_BLOCK();
|
||||||
|
|
||||||
@@ -144,6 +200,7 @@ void check_did_you_mean_type(String const &name, Array<Entity *> const &fields,
|
|||||||
check_did_you_mean_print(&d, prefix);
|
check_did_you_mean_print(&d, prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void check_did_you_mean_type(String const &name, Slice<Entity *> const &fields, char const *prefix = "") {
|
void check_did_you_mean_type(String const &name, Slice<Entity *> const &fields, char const *prefix = "") {
|
||||||
ERROR_BLOCK();
|
ERROR_BLOCK();
|
||||||
|
|
||||||
@@ -4420,7 +4477,12 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ
|
|||||||
if (operand->type != nullptr && selector->kind == Ast_Ident) {
|
if (operand->type != nullptr && selector->kind == Ast_Ident) {
|
||||||
String const &name = selector->Ident.token.string;
|
String const &name = selector->Ident.token.string;
|
||||||
Type *bt = base_type(operand->type);
|
Type *bt = base_type(operand->type);
|
||||||
if (bt->kind == Type_Struct) {
|
if (operand->type->kind == Type_Named &&
|
||||||
|
operand->type->Named.type_name &&
|
||||||
|
operand->type->Named.type_name->kind == Entity_TypeName &&
|
||||||
|
operand->type->Named.type_name->TypeName.objc_metadata) {
|
||||||
|
check_did_you_mean_objc_entity(name, operand->type->Named.type_name, operand->mode == Addressing_Type);
|
||||||
|
} else if (bt->kind == Type_Struct) {
|
||||||
check_did_you_mean_type(name, bt->Struct.fields);
|
check_did_you_mean_type(name, bt->Struct.fields);
|
||||||
} else if (bt->kind == Type_Enum) {
|
} else if (bt->kind == Type_Enum) {
|
||||||
check_did_you_mean_type(name, bt->Enum.fields);
|
check_did_you_mean_type(name, bt->Enum.fields);
|
||||||
|
|||||||
+16
-5
@@ -50,9 +50,9 @@ struct ExactValue {
|
|||||||
union {
|
union {
|
||||||
bool value_bool;
|
bool value_bool;
|
||||||
String value_string;
|
String value_string;
|
||||||
BigInt value_integer; // NOTE(bill): This must be an integer and not a pointer
|
BigInt value_integer;
|
||||||
f64 value_float;
|
f64 value_float;
|
||||||
i64 value_pointer;
|
i64 value_pointer; // NOTE(bill): This must be an integer and not a pointer
|
||||||
Complex128 *value_complex;
|
Complex128 *value_complex;
|
||||||
Quaternion256 *value_quaternion;
|
Quaternion256 *value_quaternion;
|
||||||
Ast * value_compound;
|
Ast * value_compound;
|
||||||
@@ -630,6 +630,9 @@ void match_exact_values(ExactValue *x, ExactValue *y) {
|
|||||||
case ExactValue_Bool:
|
case ExactValue_Bool:
|
||||||
case ExactValue_String:
|
case ExactValue_String:
|
||||||
case ExactValue_Quaternion:
|
case ExactValue_Quaternion:
|
||||||
|
case ExactValue_Pointer:
|
||||||
|
case ExactValue_Procedure:
|
||||||
|
case ExactValue_Typeid:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case ExactValue_Integer:
|
case ExactValue_Integer:
|
||||||
@@ -671,9 +674,6 @@ void match_exact_values(ExactValue *x, ExactValue *y) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ExactValue_Procedure:
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
compiler_error("match_exact_values: How'd you get here? Invalid ExactValueKind %d", x->kind);
|
compiler_error("match_exact_values: How'd you get here? Invalid ExactValueKind %d", x->kind);
|
||||||
@@ -932,6 +932,17 @@ bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ExactValue_Pointer: {
|
||||||
|
switch (op) {
|
||||||
|
case Token_CmpEq: return x.value_pointer == y.value_pointer;
|
||||||
|
case Token_NotEq: return x.value_pointer != y.value_pointer;
|
||||||
|
case Token_Lt: return x.value_pointer < y.value_pointer;
|
||||||
|
case Token_LtEq: return x.value_pointer <= y.value_pointer;
|
||||||
|
case Token_Gt: return x.value_pointer > y.value_pointer;
|
||||||
|
case Token_GtEq: return x.value_pointer >= y.value_pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case ExactValue_Typeid:
|
case ExactValue_Typeid:
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case Token_CmpEq: return are_types_identical(x.value_typeid, y.value_typeid);
|
case Token_CmpEq: return are_types_identical(x.value_typeid, y.value_typeid);
|
||||||
|
|||||||
@@ -6093,6 +6093,7 @@ gbFileContents gb_file_read_contents(gbAllocator a, b32 zero_terminate, char con
|
|||||||
}
|
}
|
||||||
|
|
||||||
void gb_file_free_contents(gbFileContents *fc) {
|
void gb_file_free_contents(gbFileContents *fc) {
|
||||||
|
if (fc == NULL || fc->size == 0) return;
|
||||||
GB_ASSERT_NOT_NULL(fc->data);
|
GB_ASSERT_NOT_NULL(fc->data);
|
||||||
gb_free(fc->allocator, fc->data);
|
gb_free(fc->allocator, fc->data);
|
||||||
fc->data = NULL;
|
fc->data = NULL;
|
||||||
|
|||||||
+46
-48
@@ -3015,64 +3015,62 @@ i32 token_precedence(AstFile *f, TokenKind t) {
|
|||||||
|
|
||||||
Ast *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) {
|
Ast *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) {
|
||||||
Ast *expr = parse_unary_expr(f, lhs);
|
Ast *expr = parse_unary_expr(f, lhs);
|
||||||
for (i32 prec = token_precedence(f, f->curr_token.kind); prec >= prec_in; prec--) {
|
for (;;) {
|
||||||
for (;;) {
|
Token op = f->curr_token;
|
||||||
Token op = f->curr_token;
|
i32 op_prec = token_precedence(f, op.kind);
|
||||||
i32 op_prec = token_precedence(f, op.kind);
|
if (op_prec < prec_in) {
|
||||||
if (op_prec != prec) {
|
// NOTE(bill): This will also catch operators that are not valid "binary" operators
|
||||||
// NOTE(bill): This will also catch operators that are not valid "binary" operators
|
break;
|
||||||
break;
|
}
|
||||||
|
Token prev = f->prev_token;
|
||||||
|
switch (op.kind) {
|
||||||
|
case Token_if:
|
||||||
|
case Token_when:
|
||||||
|
if (prev.pos.line < op.pos.line) {
|
||||||
|
// NOTE(bill): Check to see if the `if` or `when` is on the same line of the `lhs` condition
|
||||||
|
goto loop_end;
|
||||||
}
|
}
|
||||||
Token prev = f->prev_token;
|
break;
|
||||||
|
}
|
||||||
|
expect_operator(f); // NOTE(bill): error checks too
|
||||||
|
|
||||||
|
if (op.kind == Token_Question) {
|
||||||
|
Ast *cond = expr;
|
||||||
|
// Token_Question
|
||||||
|
Ast *x = parse_expr(f, lhs);
|
||||||
|
Token token_c = expect_token(f, Token_Colon);
|
||||||
|
Ast *y = parse_expr(f, lhs);
|
||||||
|
expr = ast_ternary_if_expr(f, x, cond, y);
|
||||||
|
} else if (op.kind == Token_if || op.kind == Token_when) {
|
||||||
|
Ast *x = expr;
|
||||||
|
Ast *cond = parse_expr(f, lhs);
|
||||||
|
Token tok_else = expect_token(f, Token_else);
|
||||||
|
Ast *y = parse_expr(f, lhs);
|
||||||
|
|
||||||
switch (op.kind) {
|
switch (op.kind) {
|
||||||
case Token_if:
|
case Token_if:
|
||||||
|
expr = ast_ternary_if_expr(f, x, cond, y);
|
||||||
|
break;
|
||||||
case Token_when:
|
case Token_when:
|
||||||
if (prev.pos.line < op.pos.line) {
|
expr = ast_ternary_when_expr(f, x, cond, y);
|
||||||
// NOTE(bill): Check to see if the `if` or `when` is on the same line of the `lhs` condition
|
|
||||||
goto loop_end;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
expect_operator(f); // NOTE(bill): error checks too
|
} else {
|
||||||
|
Ast *right = parse_binary_expr(f, false, op_prec+1);
|
||||||
if (op.kind == Token_Question) {
|
if (right == nullptr) {
|
||||||
Ast *cond = expr;
|
syntax_error(op, "Expected expression on the right-hand side of the binary operator '%.*s'", LIT(op.string));
|
||||||
// Token_Question
|
}
|
||||||
Ast *x = parse_expr(f, lhs);
|
if (op.kind == Token_or_else) {
|
||||||
Token token_c = expect_token(f, Token_Colon);
|
// NOTE(bill): easier to handle its logic different with its own AST kind
|
||||||
Ast *y = parse_expr(f, lhs);
|
expr = ast_or_else_expr(f, expr, op, right);
|
||||||
expr = ast_ternary_if_expr(f, x, cond, y);
|
|
||||||
} else if (op.kind == Token_if || op.kind == Token_when) {
|
|
||||||
Ast *x = expr;
|
|
||||||
Ast *cond = parse_expr(f, lhs);
|
|
||||||
Token tok_else = expect_token(f, Token_else);
|
|
||||||
Ast *y = parse_expr(f, lhs);
|
|
||||||
|
|
||||||
switch (op.kind) {
|
|
||||||
case Token_if:
|
|
||||||
expr = ast_ternary_if_expr(f, x, cond, y);
|
|
||||||
break;
|
|
||||||
case Token_when:
|
|
||||||
expr = ast_ternary_when_expr(f, x, cond, y);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Ast *right = parse_binary_expr(f, false, prec+1);
|
expr = ast_binary_expr(f, op, expr, right);
|
||||||
if (right == nullptr) {
|
|
||||||
syntax_error(op, "Expected expression on the right-hand side of the binary operator '%.*s'", LIT(op.string));
|
|
||||||
}
|
|
||||||
if (op.kind == Token_or_else) {
|
|
||||||
// NOTE(bill): easier to handle its logic different with its own AST kind
|
|
||||||
expr = ast_or_else_expr(f, expr, op, right);
|
|
||||||
} else {
|
|
||||||
expr = ast_binary_expr(f, op, expr, right);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lhs = false;
|
|
||||||
}
|
}
|
||||||
loop_end:;
|
|
||||||
|
lhs = false;
|
||||||
}
|
}
|
||||||
|
loop_end:;
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2623,6 +2623,17 @@ i64 union_tag_size(Type *u) {
|
|||||||
|
|
||||||
// TODO(bill): Is this an okay approach?
|
// TODO(bill): Is this an okay approach?
|
||||||
i64 max_align = 1;
|
i64 max_align = 1;
|
||||||
|
|
||||||
|
if (u->Union.variants.count < 1ull<<8) {
|
||||||
|
max_align = 1;
|
||||||
|
} else if (u->Union.variants.count < 1ull<<16) {
|
||||||
|
max_align = 2;
|
||||||
|
} else if (u->Union.variants.count < 1ull<<32) {
|
||||||
|
max_align = 4;
|
||||||
|
} else {
|
||||||
|
GB_PANIC("how many variants do you have?!");
|
||||||
|
}
|
||||||
|
|
||||||
for_array(i, u->Union.variants) {
|
for_array(i, u->Union.variants) {
|
||||||
Type *variant_type = u->Union.variants[i];
|
Type *variant_type = u->Union.variants[i];
|
||||||
i64 align = type_align_of(variant_type);
|
i64 align = type_align_of(variant_type);
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import "core:crypto/sm3"
|
|||||||
import "core:crypto/jh"
|
import "core:crypto/jh"
|
||||||
import "core:crypto/groestl"
|
import "core:crypto/groestl"
|
||||||
import "core:crypto/haval"
|
import "core:crypto/haval"
|
||||||
|
import "core:crypto/siphash"
|
||||||
|
|
||||||
TEST_count := 0
|
TEST_count := 0
|
||||||
TEST_fail := 0
|
TEST_fail := 0
|
||||||
@@ -114,6 +115,7 @@ main :: proc() {
|
|||||||
test_haval_192(&t)
|
test_haval_192(&t)
|
||||||
test_haval_224(&t)
|
test_haval_224(&t)
|
||||||
test_haval_256(&t)
|
test_haval_256(&t)
|
||||||
|
test_siphash_2_4(&t)
|
||||||
|
|
||||||
// "modern" crypto tests
|
// "modern" crypto tests
|
||||||
test_chacha20(&t)
|
test_chacha20(&t)
|
||||||
@@ -1103,3 +1105,44 @@ test_haval_256 :: proc(t: ^testing.T) {
|
|||||||
expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str))
|
expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(test)
|
||||||
|
test_siphash_2_4 :: proc(t: ^testing.T) {
|
||||||
|
// Test vectors from
|
||||||
|
// https://github.com/veorq/SipHash/blob/master/vectors.h
|
||||||
|
test_vectors := [?]u64 {
|
||||||
|
0x726fdb47dd0e0e31, 0x74f839c593dc67fd, 0x0d6c8009d9a94f5a, 0x85676696d7fb7e2d,
|
||||||
|
0xcf2794e0277187b7, 0x18765564cd99a68d, 0xcbc9466e58fee3ce, 0xab0200f58b01d137,
|
||||||
|
0x93f5f5799a932462, 0x9e0082df0ba9e4b0, 0x7a5dbbc594ddb9f3, 0xf4b32f46226bada7,
|
||||||
|
0x751e8fbc860ee5fb, 0x14ea5627c0843d90, 0xf723ca908e7af2ee, 0xa129ca6149be45e5,
|
||||||
|
0x3f2acc7f57c29bdb, 0x699ae9f52cbe4794, 0x4bc1b3f0968dd39c, 0xbb6dc91da77961bd,
|
||||||
|
0xbed65cf21aa2ee98, 0xd0f2cbb02e3b67c7, 0x93536795e3a33e88, 0xa80c038ccd5ccec8,
|
||||||
|
0xb8ad50c6f649af94, 0xbce192de8a85b8ea, 0x17d835b85bbb15f3, 0x2f2e6163076bcfad,
|
||||||
|
0xde4daaaca71dc9a5, 0xa6a2506687956571, 0xad87a3535c49ef28, 0x32d892fad841c342,
|
||||||
|
0x7127512f72f27cce, 0xa7f32346f95978e3, 0x12e0b01abb051238, 0x15e034d40fa197ae,
|
||||||
|
0x314dffbe0815a3b4, 0x027990f029623981, 0xcadcd4e59ef40c4d, 0x9abfd8766a33735c,
|
||||||
|
0x0e3ea96b5304a7d0, 0xad0c42d6fc585992, 0x187306c89bc215a9, 0xd4a60abcf3792b95,
|
||||||
|
0xf935451de4f21df2, 0xa9538f0419755787, 0xdb9acddff56ca510, 0xd06c98cd5c0975eb,
|
||||||
|
0xe612a3cb9ecba951, 0xc766e62cfcadaf96, 0xee64435a9752fe72, 0xa192d576b245165a,
|
||||||
|
0x0a8787bf8ecb74b2, 0x81b3e73d20b49b6f, 0x7fa8220ba3b2ecea, 0x245731c13ca42499,
|
||||||
|
0xb78dbfaf3a8d83bd, 0xea1ad565322a1a0b, 0x60e61c23a3795013, 0x6606d7e446282b93,
|
||||||
|
0x6ca4ecb15c5f91e1, 0x9f626da15c9625f3, 0xe51b38608ef25f57, 0x958a324ceb064572,
|
||||||
|
}
|
||||||
|
|
||||||
|
key: [16]byte
|
||||||
|
for i in 0..<16 {
|
||||||
|
key[i] = byte(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 0..<len(test_vectors) {
|
||||||
|
data := make([]byte, i)
|
||||||
|
for j in 0..<i {
|
||||||
|
data[j] = byte(j)
|
||||||
|
}
|
||||||
|
|
||||||
|
vector := test_vectors[i]
|
||||||
|
computed := siphash.sum_2_4(data[:], key[:])
|
||||||
|
|
||||||
|
expect(t, computed == vector, fmt.tprintf("Expected: 0x%x for input of %v, but got 0x%x instead", vector, data, computed))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+43
@@ -30,6 +30,7 @@ import "vendor:botan/gost"
|
|||||||
import "vendor:botan/streebog"
|
import "vendor:botan/streebog"
|
||||||
import "vendor:botan/sm3"
|
import "vendor:botan/sm3"
|
||||||
import "vendor:botan/skein512"
|
import "vendor:botan/skein512"
|
||||||
|
import "vendor:botan/siphash"
|
||||||
|
|
||||||
TEST_count := 0
|
TEST_count := 0
|
||||||
TEST_fail := 0
|
TEST_fail := 0
|
||||||
@@ -82,6 +83,7 @@ main :: proc() {
|
|||||||
test_sm3(&t)
|
test_sm3(&t)
|
||||||
test_skein512_256(&t)
|
test_skein512_256(&t)
|
||||||
test_skein512_512(&t)
|
test_skein512_512(&t)
|
||||||
|
test_siphash_2_4(&t)
|
||||||
|
|
||||||
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count)
|
||||||
}
|
}
|
||||||
@@ -575,3 +577,44 @@ test_skein512_512 :: proc(t: ^testing.T) {
|
|||||||
expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str))
|
expect(t, computed_str == v.hash, fmt.tprintf("Expected: %s for input of %s, but got %s instead", v.hash, v.str, computed_str))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(test)
|
||||||
|
test_siphash_2_4 :: proc(t: ^testing.T) {
|
||||||
|
// Test vectors from
|
||||||
|
// https://github.com/veorq/SipHash/blob/master/vectors.h
|
||||||
|
test_vectors := [?]u64 {
|
||||||
|
0x726fdb47dd0e0e31, 0x74f839c593dc67fd, 0x0d6c8009d9a94f5a, 0x85676696d7fb7e2d,
|
||||||
|
0xcf2794e0277187b7, 0x18765564cd99a68d, 0xcbc9466e58fee3ce, 0xab0200f58b01d137,
|
||||||
|
0x93f5f5799a932462, 0x9e0082df0ba9e4b0, 0x7a5dbbc594ddb9f3, 0xf4b32f46226bada7,
|
||||||
|
0x751e8fbc860ee5fb, 0x14ea5627c0843d90, 0xf723ca908e7af2ee, 0xa129ca6149be45e5,
|
||||||
|
0x3f2acc7f57c29bdb, 0x699ae9f52cbe4794, 0x4bc1b3f0968dd39c, 0xbb6dc91da77961bd,
|
||||||
|
0xbed65cf21aa2ee98, 0xd0f2cbb02e3b67c7, 0x93536795e3a33e88, 0xa80c038ccd5ccec8,
|
||||||
|
0xb8ad50c6f649af94, 0xbce192de8a85b8ea, 0x17d835b85bbb15f3, 0x2f2e6163076bcfad,
|
||||||
|
0xde4daaaca71dc9a5, 0xa6a2506687956571, 0xad87a3535c49ef28, 0x32d892fad841c342,
|
||||||
|
0x7127512f72f27cce, 0xa7f32346f95978e3, 0x12e0b01abb051238, 0x15e034d40fa197ae,
|
||||||
|
0x314dffbe0815a3b4, 0x027990f029623981, 0xcadcd4e59ef40c4d, 0x9abfd8766a33735c,
|
||||||
|
0x0e3ea96b5304a7d0, 0xad0c42d6fc585992, 0x187306c89bc215a9, 0xd4a60abcf3792b95,
|
||||||
|
0xf935451de4f21df2, 0xa9538f0419755787, 0xdb9acddff56ca510, 0xd06c98cd5c0975eb,
|
||||||
|
0xe612a3cb9ecba951, 0xc766e62cfcadaf96, 0xee64435a9752fe72, 0xa192d576b245165a,
|
||||||
|
0x0a8787bf8ecb74b2, 0x81b3e73d20b49b6f, 0x7fa8220ba3b2ecea, 0x245731c13ca42499,
|
||||||
|
0xb78dbfaf3a8d83bd, 0xea1ad565322a1a0b, 0x60e61c23a3795013, 0x6606d7e446282b93,
|
||||||
|
0x6ca4ecb15c5f91e1, 0x9f626da15c9625f3, 0xe51b38608ef25f57, 0x958a324ceb064572,
|
||||||
|
}
|
||||||
|
|
||||||
|
key: [16]byte
|
||||||
|
for i in 0..<16 {
|
||||||
|
key[i] = byte(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 0..<len(test_vectors) {
|
||||||
|
data := make([]byte, i)
|
||||||
|
for j in 0..<i {
|
||||||
|
data[j] = byte(j)
|
||||||
|
}
|
||||||
|
|
||||||
|
vector := test_vectors[i]
|
||||||
|
computed := siphash.sum_2_4(data[:], key[:])
|
||||||
|
|
||||||
|
expect(t, computed == vector, fmt.tprintf("Expected: 0x%x for input of %v, but got 0x%x instead", vector, data, computed))
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+4
@@ -99,6 +99,10 @@ MAC_HMAC_SHA_384 :: "HMAC(SHA-384)"
|
|||||||
MAC_HMAC_SHA_512 :: "HMAC(SHA-512)"
|
MAC_HMAC_SHA_512 :: "HMAC(SHA-512)"
|
||||||
MAC_HMAC_MD5 :: "HMAC(MD5)"
|
MAC_HMAC_MD5 :: "HMAC(MD5)"
|
||||||
|
|
||||||
|
MAC_SIPHASH_1_3 :: "SipHash(1,3)"
|
||||||
|
MAC_SIPHASH_2_4 :: "SipHash(2,4)"
|
||||||
|
MAC_SIPHASH_4_8 :: "SipHash(4,8)"
|
||||||
|
|
||||||
hash_struct :: struct{}
|
hash_struct :: struct{}
|
||||||
hash_t :: ^hash_struct
|
hash_t :: ^hash_struct
|
||||||
rng_struct :: struct{}
|
rng_struct :: struct{}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -44,7 +44,7 @@ hash_bytes :: proc "contextless" (data: []byte) -> [DIGEST_SIZE]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer will hash the given input and write the
|
// hash_bytes_to_buffer will hash the given input and write the
|
||||||
|
|||||||
Vendored
+1
-1
@@ -44,7 +44,7 @@ hash_bytes :: proc "contextless" (data: []byte) -> [DIGEST_SIZE]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer will hash the given input and write the
|
// hash_bytes_to_buffer will hash the given input and write the
|
||||||
|
|||||||
Vendored
+1
-1
@@ -44,7 +44,7 @@ hash_bytes_512 :: proc(data: []byte) -> [DIGEST_SIZE_512]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer_512 :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer_512 :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer_512(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer_512(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer_512 will hash the given input and write the
|
// hash_bytes_to_buffer_512 will hash the given input and write the
|
||||||
|
|||||||
Vendored
+1
-1
@@ -44,7 +44,7 @@ hash_bytes :: proc "contextless" (data: []byte) -> [DIGEST_SIZE]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer will hash the given input and write the
|
// hash_bytes_to_buffer will hash the given input and write the
|
||||||
|
|||||||
Vendored
+1
-1
@@ -44,7 +44,7 @@ hash_bytes :: proc "contextless" (data: []byte) -> [DIGEST_SIZE]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer will hash the given input and write the
|
// hash_bytes_to_buffer will hash the given input and write the
|
||||||
|
|||||||
Vendored
+1
-1
@@ -44,7 +44,7 @@ hash_bytes_160 :: proc(data: []byte) -> [DIGEST_SIZE_160]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer_160 :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer_160 :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer_160(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer_160(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer_160 will hash the given input and write the
|
// hash_bytes_to_buffer_160 will hash the given input and write the
|
||||||
|
|||||||
Vendored
+1
-1
@@ -44,7 +44,7 @@ hash_bytes :: proc "contextless" (data: []byte) -> [DIGEST_SIZE]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer will hash the given input and write the
|
// hash_bytes_to_buffer will hash the given input and write the
|
||||||
|
|||||||
Vendored
+4
-4
@@ -47,7 +47,7 @@ hash_bytes_224 :: proc(data: []byte) -> [DIGEST_SIZE_224]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer_224 :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer_224 :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer_224(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer_224(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer_224 will hash the given input and write the
|
// hash_bytes_to_buffer_224 will hash the given input and write the
|
||||||
@@ -126,7 +126,7 @@ hash_bytes_256 :: proc(data: []byte) -> [DIGEST_SIZE_256]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer_256 :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer_256 :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer_256(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer_256(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer_256 will hash the given input and write the
|
// hash_bytes_to_buffer_256 will hash the given input and write the
|
||||||
@@ -205,7 +205,7 @@ hash_bytes_384 :: proc(data: []byte) -> [DIGEST_SIZE_384]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer_384 :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer_384 :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer_384(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer_384(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer_384 will hash the given input and write the
|
// hash_bytes_to_buffer_384 will hash the given input and write the
|
||||||
@@ -284,7 +284,7 @@ hash_bytes_512 :: proc(data: []byte) -> [DIGEST_SIZE_512]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer_512 :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer_512 :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer_512(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer_512(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer_512 will hash the given input and write the
|
// hash_bytes_to_buffer_512 will hash the given input and write the
|
||||||
|
|||||||
Vendored
+4
-4
@@ -47,7 +47,7 @@ hash_bytes_224 :: proc(data: []byte) -> [DIGEST_SIZE_224]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer_224 :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer_224 :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer_224(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer_224(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer_224 will hash the given input and write the
|
// hash_bytes_to_buffer_224 will hash the given input and write the
|
||||||
@@ -126,7 +126,7 @@ hash_bytes_256 :: proc(data: []byte) -> [DIGEST_SIZE_256]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer_256 :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer_256 :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer_256(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer_256(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer_256 will hash the given input and write the
|
// hash_bytes_to_buffer_256 will hash the given input and write the
|
||||||
@@ -205,7 +205,7 @@ hash_bytes_384 :: proc(data: []byte) -> [DIGEST_SIZE_384]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer_384 :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer_384 :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer_384(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer_384(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer_384 will hash the given input and write the
|
// hash_bytes_to_buffer_384 will hash the given input and write the
|
||||||
@@ -284,7 +284,7 @@ hash_bytes_512 :: proc(data: []byte) -> [DIGEST_SIZE_512]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer_512 :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer_512 :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer_512(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer_512(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer_512 will hash the given input and write the
|
// hash_bytes_to_buffer_512 will hash the given input and write the
|
||||||
|
|||||||
Vendored
+2
-2
@@ -45,7 +45,7 @@ hash_bytes_128 :: proc(data: []byte) -> [DIGEST_SIZE_128]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer_128 :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer_128 :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer_128(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer_128(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer_128 will hash the given input and write the
|
// hash_bytes_to_buffer_128 will hash the given input and write the
|
||||||
@@ -124,7 +124,7 @@ hash_bytes_256 :: proc(data: []byte) -> [DIGEST_SIZE_256]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer_256 :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer_256 :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer_256(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer_256(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer_256 will hash the given input and write the
|
// hash_bytes_to_buffer_256 will hash the given input and write the
|
||||||
|
|||||||
Vendored
+253
@@ -0,0 +1,253 @@
|
|||||||
|
package siphash
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2022 zhibog
|
||||||
|
Made available under the BSD-3 license.
|
||||||
|
|
||||||
|
List of contributors:
|
||||||
|
zhibog: Initial implementation.
|
||||||
|
|
||||||
|
Interface for the SipHash hashing algorithm.
|
||||||
|
The hash will be computed via bindings to the Botan crypto library
|
||||||
|
|
||||||
|
Use the specific procedures for a certain setup. The generic procdedures will default to Siphash 2-4
|
||||||
|
*/
|
||||||
|
|
||||||
|
import "core:crypto"
|
||||||
|
import "core:crypto/util"
|
||||||
|
|
||||||
|
import botan "../bindings"
|
||||||
|
|
||||||
|
KEY_SIZE :: 16
|
||||||
|
DIGEST_SIZE :: 8
|
||||||
|
|
||||||
|
// sum_string_1_3 will hash the given message with the key and return
|
||||||
|
// the computed hash as a u64
|
||||||
|
sum_string_1_3 :: proc(msg, key: string) -> u64 {
|
||||||
|
return sum_bytes_1_3(transmute([]byte)(msg), transmute([]byte)(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_bytes_1_3 will hash the given message with the key and return
|
||||||
|
// the computed hash as a u64
|
||||||
|
sum_bytes_1_3 :: proc (msg, key: []byte) -> u64 {
|
||||||
|
dst: [8]byte
|
||||||
|
ctx: botan.mac_t
|
||||||
|
init(&ctx, key[:], 1, 3)
|
||||||
|
update(&ctx, msg[:])
|
||||||
|
final(&ctx, dst[:])
|
||||||
|
return util.U64_LE(dst[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_string_to_buffer_1_3 will hash the given message with the key and write
|
||||||
|
// the computed hash into the provided destination buffer
|
||||||
|
sum_string_to_buffer_1_3 :: proc(msg, key: string, dst: []byte) {
|
||||||
|
sum_bytes_to_buffer_1_3(transmute([]byte)(msg), transmute([]byte)(key), dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_bytes_to_buffer_1_3 will hash the given message with the key and write
|
||||||
|
// the computed hash into the provided destination buffer
|
||||||
|
sum_bytes_to_buffer_1_3 :: proc(msg, key, dst: []byte) {
|
||||||
|
assert(len(dst) >= DIGEST_SIZE, "vendor/botan: Destination buffer needs to be at least of size 8")
|
||||||
|
ctx: botan.mac_t
|
||||||
|
init(&ctx, key[:], 1, 3)
|
||||||
|
update(&ctx, msg[:])
|
||||||
|
final(&ctx, dst[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
sum_1_3 :: proc {
|
||||||
|
sum_string_1_3,
|
||||||
|
sum_bytes_1_3,
|
||||||
|
sum_string_to_buffer_1_3,
|
||||||
|
sum_bytes_to_buffer_1_3,
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify_u64_1_3 will check if the supplied tag matches with the output you
|
||||||
|
// will get from the provided message and key
|
||||||
|
verify_u64_1_3 :: proc (tag: u64 msg, key: []byte) -> bool {
|
||||||
|
return sum_bytes_1_3(msg, key) == tag
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify_bytes_1_3 will check if the supplied tag matches with the output you
|
||||||
|
// will get from the provided message and key
|
||||||
|
verify_bytes_1_3 :: proc (tag, msg, key: []byte) -> bool {
|
||||||
|
derived_tag: [8]byte
|
||||||
|
sum_bytes_to_buffer_1_3(msg, key, derived_tag[:])
|
||||||
|
return crypto.compare_constant_time(derived_tag[:], tag) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
verify_1_3 :: proc {
|
||||||
|
verify_bytes_1_3,
|
||||||
|
verify_u64_1_3,
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_string_2_4 will hash the given message with the key and return
|
||||||
|
// the computed hash as a u64
|
||||||
|
sum_string_2_4 :: proc(msg, key: string) -> u64 {
|
||||||
|
return sum_bytes_2_4(transmute([]byte)(msg), transmute([]byte)(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_bytes_2_4 will hash the given message with the key and return
|
||||||
|
// the computed hash as a u64
|
||||||
|
sum_bytes_2_4 :: proc (msg, key: []byte) -> u64 {
|
||||||
|
dst: [8]byte
|
||||||
|
ctx: botan.mac_t
|
||||||
|
init(&ctx, key[:])
|
||||||
|
update(&ctx, msg[:])
|
||||||
|
final(&ctx, dst[:])
|
||||||
|
return util.U64_LE(dst[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_string_to_buffer_2_4 will hash the given message with the key and write
|
||||||
|
// the computed hash into the provided destination buffer
|
||||||
|
sum_string_to_buffer_2_4 :: proc(msg, key: string, dst: []byte) {
|
||||||
|
sum_bytes_to_buffer_2_4(transmute([]byte)(msg), transmute([]byte)(key), dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_bytes_to_buffer_2_4 will hash the given message with the key and write
|
||||||
|
// the computed hash into the provided destination buffer
|
||||||
|
sum_bytes_to_buffer_2_4 :: proc(msg, key, dst: []byte) {
|
||||||
|
assert(len(dst) >= DIGEST_SIZE, "vendor/botan: Destination buffer needs to be at least of size 8")
|
||||||
|
ctx: botan.mac_t
|
||||||
|
init(&ctx, key[:])
|
||||||
|
update(&ctx, msg[:])
|
||||||
|
final(&ctx, dst[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
sum_2_4 :: proc {
|
||||||
|
sum_string_2_4,
|
||||||
|
sum_bytes_2_4,
|
||||||
|
sum_string_to_buffer_2_4,
|
||||||
|
sum_bytes_to_buffer_2_4,
|
||||||
|
}
|
||||||
|
|
||||||
|
sum_string :: sum_string_2_4
|
||||||
|
sum_bytes :: sum_bytes_2_4
|
||||||
|
sum_string_to_buffer :: sum_string_to_buffer_2_4
|
||||||
|
sum_bytes_to_buffer :: sum_bytes_to_buffer_2_4
|
||||||
|
sum :: proc {
|
||||||
|
sum_string,
|
||||||
|
sum_bytes,
|
||||||
|
sum_string_to_buffer,
|
||||||
|
sum_bytes_to_buffer,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// verify_u64_2_4 will check if the supplied tag matches with the output you
|
||||||
|
// will get from the provided message and key
|
||||||
|
verify_u64_2_4 :: proc (tag: u64 msg, key: []byte) -> bool {
|
||||||
|
return sum_bytes_2_4(msg, key) == tag
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify_bytes_2_4 will check if the supplied tag matches with the output you
|
||||||
|
// will get from the provided message and key
|
||||||
|
verify_bytes_2_4 :: proc (tag, msg, key: []byte) -> bool {
|
||||||
|
derived_tag: [8]byte
|
||||||
|
sum_bytes_to_buffer_2_4(msg, key, derived_tag[:])
|
||||||
|
return crypto.compare_constant_time(derived_tag[:], tag) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
verify_2_4 :: proc {
|
||||||
|
verify_bytes_2_4,
|
||||||
|
verify_u64_2_4,
|
||||||
|
}
|
||||||
|
|
||||||
|
verify_bytes :: verify_bytes_2_4
|
||||||
|
verify_u64 :: verify_u64_2_4
|
||||||
|
verify :: proc {
|
||||||
|
verify_bytes,
|
||||||
|
verify_u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_string_4_8 will hash the given message with the key and return
|
||||||
|
// the computed hash as a u64
|
||||||
|
sum_string_4_8 :: proc(msg, key: string) -> u64 {
|
||||||
|
return sum_bytes_4_8(transmute([]byte)(msg), transmute([]byte)(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_bytes_4_8 will hash the given message with the key and return
|
||||||
|
// the computed hash as a u64
|
||||||
|
sum_bytes_4_8 :: proc (msg, key: []byte) -> u64 {
|
||||||
|
dst: [8]byte
|
||||||
|
ctx: botan.mac_t
|
||||||
|
init(&ctx, key[:], 4, 8)
|
||||||
|
update(&ctx, msg[:])
|
||||||
|
final(&ctx, dst[:])
|
||||||
|
return util.U64_LE(dst[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_string_to_buffer_4_8 will hash the given message with the key and write
|
||||||
|
// the computed hash into the provided destination buffer
|
||||||
|
sum_string_to_buffer_4_8 :: proc(msg, key: string, dst: []byte) {
|
||||||
|
sum_bytes_to_buffer_2_4(transmute([]byte)(msg), transmute([]byte)(key), dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sum_bytes_to_buffer_4_8 will hash the given message with the key and write
|
||||||
|
// the computed hash into the provided destination buffer
|
||||||
|
sum_bytes_to_buffer_4_8 :: proc(msg, key, dst: []byte) {
|
||||||
|
assert(len(dst) >= DIGEST_SIZE, "vendor/botan: Destination buffer needs to be at least of size 8")
|
||||||
|
ctx: botan.mac_t
|
||||||
|
init(&ctx, key[:], 4, 8)
|
||||||
|
update(&ctx, msg[:])
|
||||||
|
final(&ctx, dst[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
sum_4_8 :: proc {
|
||||||
|
sum_string_4_8,
|
||||||
|
sum_bytes_4_8,
|
||||||
|
sum_string_to_buffer_4_8,
|
||||||
|
sum_bytes_to_buffer_4_8,
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify_u64_4_8 will check if the supplied tag matches with the output you
|
||||||
|
// will get from the provided message and key
|
||||||
|
verify_u64_4_8 :: proc (tag: u64 msg, key: []byte) -> bool {
|
||||||
|
return sum_bytes_4_8(msg, key) == tag
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify_bytes_4_8 will check if the supplied tag matches with the output you
|
||||||
|
// will get from the provided message and key
|
||||||
|
verify_bytes_4_8 :: proc (tag, msg, key: []byte) -> bool {
|
||||||
|
derived_tag: [8]byte
|
||||||
|
sum_bytes_to_buffer_4_8(msg, key, derived_tag[:])
|
||||||
|
return crypto.compare_constant_time(derived_tag[:], tag) == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
verify_4_8 :: proc {
|
||||||
|
verify_bytes_4_8,
|
||||||
|
verify_u64_4_8,
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Low level API
|
||||||
|
*/
|
||||||
|
|
||||||
|
Context :: botan.mac_t
|
||||||
|
|
||||||
|
init :: proc(ctx: ^botan.mac_t, key: []byte, c_rounds := 2, d_rounds := 4) {
|
||||||
|
assert(len(key) == KEY_SIZE, "vendor/botan: Invalid key size, want 16")
|
||||||
|
is_valid_setting := (c_rounds == 1 && d_rounds == 3) ||
|
||||||
|
(c_rounds == 2 && d_rounds == 4) ||
|
||||||
|
(c_rounds == 4 && d_rounds == 8)
|
||||||
|
assert(is_valid_setting, "vendor/botan: Incorrect rounds set up. Valid pairs are (1,3), (2,4) and (4,8)")
|
||||||
|
if c_rounds == 1 && d_rounds == 3 {
|
||||||
|
botan.mac_init(ctx, botan.MAC_SIPHASH_1_3, 0)
|
||||||
|
} else if c_rounds == 2 && d_rounds == 4 {
|
||||||
|
botan.mac_init(ctx, botan.MAC_SIPHASH_2_4, 0)
|
||||||
|
} else if c_rounds == 4 && d_rounds == 8 {
|
||||||
|
botan.mac_init(ctx, botan.MAC_SIPHASH_4_8, 0)
|
||||||
|
}
|
||||||
|
botan.mac_set_key(ctx^, len(key) == 0 ? nil : &key[0], uint(len(key)))
|
||||||
|
}
|
||||||
|
|
||||||
|
update :: proc "contextless" (ctx: ^botan.mac_t, data: []byte) {
|
||||||
|
botan.mac_update(ctx^, len(data) == 0 ? nil : &data[0], uint(len(data)))
|
||||||
|
}
|
||||||
|
|
||||||
|
final :: proc(ctx: ^botan.mac_t, dst: []byte) {
|
||||||
|
botan.mac_final(ctx^, &dst[0])
|
||||||
|
reset(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
reset :: proc(ctx: ^botan.mac_t) {
|
||||||
|
botan.mac_destroy(ctx^)
|
||||||
|
}
|
||||||
Vendored
+3
-3
@@ -47,7 +47,7 @@ hash_bytes_256 :: proc(data: []byte) -> [DIGEST_SIZE_256]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer_256 :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer_256 :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer_256(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer_256(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer_256 will hash the given input and write the
|
// hash_bytes_to_buffer_256 will hash the given input and write the
|
||||||
@@ -126,7 +126,7 @@ hash_bytes_512 :: proc(data: []byte) -> [DIGEST_SIZE_512]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer_512 :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer_512 :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer_512(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer_512(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer_512 will hash the given input and write the
|
// hash_bytes_to_buffer_512 will hash the given input and write the
|
||||||
@@ -205,7 +205,7 @@ hash_bytes_slice :: proc(data: []byte, bit_size: int, allocator := context.alloc
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer_slice :: proc(data: string, hash: []byte, bit_size: int, allocator := context.allocator) {
|
hash_string_to_buffer_slice :: proc(data: string, hash: []byte, bit_size: int, allocator := context.allocator) {
|
||||||
hash_bytes_to_buffer_slice(transmute([]byte)(data), hash, bit_size, allocator);
|
hash_bytes_to_buffer_slice(transmute([]byte)(data), hash, bit_size, allocator)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer_slice will hash the given input and write the
|
// hash_bytes_to_buffer_slice will hash the given input and write the
|
||||||
|
|||||||
Vendored
+1
-1
@@ -44,7 +44,7 @@ hash_bytes :: proc "contextless" (data: []byte) -> [DIGEST_SIZE]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer will hash the given input and write the
|
// hash_bytes_to_buffer will hash the given input and write the
|
||||||
|
|||||||
Vendored
+2
-2
@@ -45,7 +45,7 @@ hash_bytes_256 :: proc(data: []byte) -> [DIGEST_SIZE_256]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer_256 :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer_256 :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer_256(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer_256(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer_256 will hash the given input and write the
|
// hash_bytes_to_buffer_256 will hash the given input and write the
|
||||||
@@ -124,7 +124,7 @@ hash_bytes_512 :: proc(data: []byte) -> [DIGEST_SIZE_512]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer_512 :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer_512 :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer_512(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer_512(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer_512 will hash the given input and write the
|
// hash_bytes_to_buffer_512 will hash the given input and write the
|
||||||
|
|||||||
Vendored
+3
-3
@@ -46,7 +46,7 @@ hash_bytes_128 :: proc(data: []byte) -> [DIGEST_SIZE_128]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer_128 :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer_128 :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer_128(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer_128(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer_128 will hash the given input and write the
|
// hash_bytes_to_buffer_128 will hash the given input and write the
|
||||||
@@ -125,7 +125,7 @@ hash_bytes_160 :: proc(data: []byte) -> [DIGEST_SIZE_160]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer_160 :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer_160 :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer_160(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer_160(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer_160 will hash the given input and write the
|
// hash_bytes_to_buffer_160 will hash the given input and write the
|
||||||
@@ -204,7 +204,7 @@ hash_bytes_192 :: proc(data: []byte) -> [DIGEST_SIZE_192]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer_192 :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer_192 :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer_192(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer_192(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer_192 will hash the given input and write the
|
// hash_bytes_to_buffer_192 will hash the given input and write the
|
||||||
|
|||||||
+1
-1
@@ -44,7 +44,7 @@ hash_bytes :: proc "contextless" (data: []byte) -> [DIGEST_SIZE]byte {
|
|||||||
// computed hash to the second parameter.
|
// computed hash to the second parameter.
|
||||||
// It requires that the destination buffer is at least as big as the digest size
|
// It requires that the destination buffer is at least as big as the digest size
|
||||||
hash_string_to_buffer :: proc(data: string, hash: []byte) {
|
hash_string_to_buffer :: proc(data: string, hash: []byte) {
|
||||||
hash_bytes_to_buffer(transmute([]byte)(data), hash);
|
hash_bytes_to_buffer(transmute([]byte)(data), hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hash_bytes_to_buffer will hash the given input and write the
|
// hash_bytes_to_buffer will hash the given input and write the
|
||||||
|
|||||||
+20
-20
@@ -5508,8 +5508,8 @@ Buffer_newRemoteBufferViewForDevice :: #force_inline proc(self: ^Buffer, device:
|
|||||||
return msgSend(^Buffer, self, "newRemoteBufferViewForDevice:", device)
|
return msgSend(^Buffer, self, "newRemoteBufferViewForDevice:", device)
|
||||||
}
|
}
|
||||||
@(objc_type=Buffer, objc_name="newTexture")
|
@(objc_type=Buffer, objc_name="newTexture")
|
||||||
Buffer_newTexture :: #force_inline proc(self: ^Buffer, descriptor: ^TextureDescriptor, offset: NS.UInteger, bytesPerRow: NS.UInteger) -> ^Buffer {
|
Buffer_newTexture :: #force_inline proc(self: ^Buffer, descriptor: ^TextureDescriptor, offset: NS.UInteger, bytesPerRow: NS.UInteger) -> ^Texture {
|
||||||
return msgSend(^Buffer, self, "newTextureWithDescriptor:offset:bytesPerRow:", descriptor, offset, bytesPerRow)
|
return msgSend(^Texture, self, "newTextureWithDescriptor:offset:bytesPerRow:", descriptor, offset, bytesPerRow)
|
||||||
}
|
}
|
||||||
@(objc_type=Buffer, objc_name="remoteStorageBuffer")
|
@(objc_type=Buffer, objc_name="remoteStorageBuffer")
|
||||||
Buffer_remoteStorageBuffer :: #force_inline proc(self: ^Buffer) -> ^Buffer {
|
Buffer_remoteStorageBuffer :: #force_inline proc(self: ^Buffer) -> ^Buffer {
|
||||||
@@ -6589,8 +6589,8 @@ Device_newRasterizationRateMap :: #force_inline proc(self: ^Device, descriptor:
|
|||||||
return msgSend(^RasterizationRateMap, self, "newRasterizationRateMapWithDescriptor:", descriptor)
|
return msgSend(^RasterizationRateMap, self, "newRasterizationRateMapWithDescriptor:", descriptor)
|
||||||
}
|
}
|
||||||
@(objc_type=Device, objc_name="newRenderPipelineStateWithDescriptorWithCompletionHandler")
|
@(objc_type=Device, objc_name="newRenderPipelineStateWithDescriptorWithCompletionHandler")
|
||||||
Device_newRenderPipelineStateWithDescriptorWithCompletionHandler :: #force_inline proc(self: ^Device, descriptor: ^RenderPipelineDescriptor, completionHandler: NewRenderPipelineStateCompletionHandler) {
|
Device_newRenderPipelineStateWithDescriptorWithCompletionHandler :: #force_inline proc(self: ^Device, descriptor: ^RenderPipelineDescriptor, completionHandler: NewRenderPipelineStateCompletionHandler) -> ^RenderPipelineState {
|
||||||
msgSend(nil, self, "newRenderPipelineStateWithDescriptor:completionHandler:", descriptor, completionHandler)
|
return msgSend(^RenderPipelineState, self, "newRenderPipelineStateWithDescriptor:completionHandler:", descriptor, completionHandler)
|
||||||
}
|
}
|
||||||
@(objc_type=Device, objc_name="newRenderPipelineState")
|
@(objc_type=Device, objc_name="newRenderPipelineState")
|
||||||
Device_newRenderPipelineState :: #force_inline proc(self: ^Device, descriptor: ^RenderPipelineDescriptor) -> (pipeline: ^RenderPipelineState, error: ^NS.Error) {
|
Device_newRenderPipelineState :: #force_inline proc(self: ^Device, descriptor: ^RenderPipelineDescriptor) -> (pipeline: ^RenderPipelineState, error: ^NS.Error) {
|
||||||
@@ -6598,8 +6598,8 @@ Device_newRenderPipelineState :: #force_inline proc(self: ^Device, descriptor: ^
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
@(objc_type=Device, objc_name="newRenderPipelineStateWithDescriptorWithOptionsAndCompletionHandler")
|
@(objc_type=Device, objc_name="newRenderPipelineStateWithDescriptorWithOptionsAndCompletionHandler")
|
||||||
Device_newRenderPipelineStateWithDescriptorWithOptionsAndCompletionHandler :: #force_inline proc(self: ^Device, descriptor: ^RenderPipelineDescriptor, options: PipelineOption, completionHandler: NewRenderPipelineStateWithReflectionCompletionHandler) {
|
Device_newRenderPipelineStateWithDescriptorWithOptionsAndCompletionHandler :: #force_inline proc(self: ^Device, descriptor: ^RenderPipelineDescriptor, options: PipelineOption, completionHandler: NewRenderPipelineStateWithReflectionCompletionHandler) -> ^RenderPipelineState {
|
||||||
msgSend(nil, self, "newRenderPipelineStateWithDescriptor:options:completionHandler:", descriptor, options, completionHandler)
|
return msgSend(^RenderPipelineState, self, "newRenderPipelineStateWithDescriptor:options:completionHandler:", descriptor, options, completionHandler)
|
||||||
}
|
}
|
||||||
@(objc_type=Device, objc_name="newRenderPipelineStateWithDescriptorWithReflection")
|
@(objc_type=Device, objc_name="newRenderPipelineStateWithDescriptorWithReflection")
|
||||||
Device_newRenderPipelineStateWithDescriptorWithReflection :: #force_inline proc(self: ^Device, descriptor: ^RenderPipelineDescriptor, options: PipelineOption, reflection: ^AutoreleasedRenderPipelineReflection) -> (pipeline: ^RenderPipelineState, error: ^NS.Error) {
|
Device_newRenderPipelineStateWithDescriptorWithReflection :: #force_inline proc(self: ^Device, descriptor: ^RenderPipelineDescriptor, options: PipelineOption, reflection: ^AutoreleasedRenderPipelineReflection) -> (pipeline: ^RenderPipelineState, error: ^NS.Error) {
|
||||||
@@ -6607,8 +6607,8 @@ Device_newRenderPipelineStateWithDescriptorWithReflection :: #force_inline proc(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
@(objc_type=Device, objc_name="newRenderPipelineStateWithTileDescriptorWithCompletionHandler")
|
@(objc_type=Device, objc_name="newRenderPipelineStateWithTileDescriptorWithCompletionHandler")
|
||||||
Device_newRenderPipelineStateWithTileDescriptorWithCompletionHandler :: #force_inline proc(self: ^Device, descriptor: ^TileRenderPipelineDescriptor, options: PipelineOption, completionHandler: NewRenderPipelineStateWithReflectionCompletionHandler) {
|
Device_newRenderPipelineStateWithTileDescriptorWithCompletionHandler :: #force_inline proc(self: ^Device, descriptor: ^TileRenderPipelineDescriptor, options: PipelineOption, completionHandler: NewRenderPipelineStateWithReflectionCompletionHandler) -> ^RenderPipelineState {
|
||||||
msgSend(nil, self, "newRenderPipelineStateWithTileDescriptor:options:completionHandler:", descriptor, options, completionHandler)
|
return msgSend(^RenderPipelineState, self, "newRenderPipelineStateWithTileDescriptor:options:completionHandler:", descriptor, options, completionHandler)
|
||||||
}
|
}
|
||||||
@(objc_type=Device, objc_name="newRenderPipelineStateWithTileDescriptorWithReflection")
|
@(objc_type=Device, objc_name="newRenderPipelineStateWithTileDescriptorWithReflection")
|
||||||
Device_newRenderPipelineStateWithTileDescriptorWithReflection :: #force_inline proc(self: ^Device, descriptor: ^TileRenderPipelineDescriptor, options: PipelineOption, reflection: ^AutoreleasedRenderPipelineReflection) -> (pipeline: ^RenderPipelineState, error: ^NS.Error) {
|
Device_newRenderPipelineStateWithTileDescriptorWithReflection :: #force_inline proc(self: ^Device, descriptor: ^TileRenderPipelineDescriptor, options: PipelineOption, reflection: ^AutoreleasedRenderPipelineReflection) -> (pipeline: ^RenderPipelineState, error: ^NS.Error) {
|
||||||
@@ -6636,8 +6636,8 @@ Device_newSharedTextureWithHandle :: #force_inline proc(self: ^Device, sharedHan
|
|||||||
return msgSend(^SharedEvent, self, "newSharedTextureWithHandle:", sharedHandle)
|
return msgSend(^SharedEvent, self, "newSharedTextureWithHandle:", sharedHandle)
|
||||||
}
|
}
|
||||||
@(objc_type=Device, objc_name="newTexture")
|
@(objc_type=Device, objc_name="newTexture")
|
||||||
Device_newTexture :: #force_inline proc(self: ^Device, desc: ^TextureDescriptor) -> ^SharedEvent {
|
Device_newTexture :: #force_inline proc(self: ^Device, desc: ^TextureDescriptor) -> ^Texture {
|
||||||
return msgSend(^SharedEvent, self, "newTextureWithDescriptor:", desc)
|
return msgSend(^Texture, self, "newTextureWithDescriptor:", desc)
|
||||||
}
|
}
|
||||||
@(objc_type=Device, objc_name="newTextureWithIOSurface")
|
@(objc_type=Device, objc_name="newTextureWithIOSurface")
|
||||||
Device_newTextureWithIOSurface :: #force_inline proc(self: ^Device, descriptor: ^TextureDescriptor, iosurface: IOSurfaceRef, plane: NS.UInteger) -> ^Texture {
|
Device_newTextureWithIOSurface :: #force_inline proc(self: ^Device, descriptor: ^TextureDescriptor, iosurface: IOSurfaceRef, plane: NS.UInteger) -> ^Texture {
|
||||||
@@ -7101,24 +7101,24 @@ Heap_label :: #force_inline proc(self: ^Heap) -> ^NS.String {
|
|||||||
return msgSend(^NS.String, self, "label")
|
return msgSend(^NS.String, self, "label")
|
||||||
}
|
}
|
||||||
@(objc_type=Heap, objc_name="maxAvailableSizeWithAlignment")
|
@(objc_type=Heap, objc_name="maxAvailableSizeWithAlignment")
|
||||||
Heap_maxAvailableSizeWithAlignment :: #force_inline proc(self: ^Heap, alignment: NS.UInteger) -> ^Heap {
|
Heap_maxAvailableSizeWithAlignment :: #force_inline proc(self: ^Heap, alignment: NS.UInteger) -> NS.UInteger {
|
||||||
return msgSend(^Heap, self, "maxAvailableSizeWithAlignment:", alignment)
|
return msgSend(NS.UInteger, self, "maxAvailableSizeWithAlignment:", alignment)
|
||||||
}
|
}
|
||||||
@(objc_type=Heap, objc_name="newBuffer")
|
@(objc_type=Heap, objc_name="newBuffer")
|
||||||
Heap_newBuffer :: #force_inline proc(self: ^Heap, length: NS.UInteger, options: ResourceOptions) -> ^Heap {
|
Heap_newBuffer :: #force_inline proc(self: ^Heap, length: NS.UInteger, options: ResourceOptions) -> ^Buffer {
|
||||||
return msgSend(^Heap, self, "newBufferWithLength:options:", length, options)
|
return msgSend(^Buffer, self, "newBufferWithLength:options:", length, options)
|
||||||
}
|
}
|
||||||
@(objc_type=Heap, objc_name="newBufferWithOptions")
|
@(objc_type=Heap, objc_name="newBufferWithOptions")
|
||||||
Heap_newBufferWithOptions :: #force_inline proc(self: ^Heap, length: NS.UInteger, options: ResourceOptions, offset: NS.UInteger) -> ^Heap {
|
Heap_newBufferWithOptions :: #force_inline proc(self: ^Heap, length: NS.UInteger, options: ResourceOptions, offset: NS.UInteger) -> ^Buffer {
|
||||||
return msgSend(^Heap, self, "newBufferWithLength:options:offset:", length, options, offset)
|
return msgSend(^Buffer, self, "newBufferWithLength:options:offset:", length, options, offset)
|
||||||
}
|
}
|
||||||
@(objc_type=Heap, objc_name="newTexture")
|
@(objc_type=Heap, objc_name="newTexture")
|
||||||
Heap_newTexture :: #force_inline proc(self: ^Heap, desc: ^TextureDescriptor) -> ^Heap {
|
Heap_newTexture :: #force_inline proc(self: ^Heap, desc: ^TextureDescriptor) -> ^Texture {
|
||||||
return msgSend(^Heap, self, "newTextureWithDescriptor:", desc)
|
return msgSend(^Texture, self, "newTextureWithDescriptor:", desc)
|
||||||
}
|
}
|
||||||
@(objc_type=Heap, objc_name="newTextureWithOffset")
|
@(objc_type=Heap, objc_name="newTextureWithOffset")
|
||||||
Heap_newTextureWithOffset :: #force_inline proc(self: ^Heap, descriptor: ^TextureDescriptor, offset: NS.UInteger) -> ^Heap {
|
Heap_newTextureWithOffset :: #force_inline proc(self: ^Heap, descriptor: ^TextureDescriptor, offset: NS.UInteger) -> ^Texture {
|
||||||
return msgSend(^Heap, self, "newTextureWithDescriptor:offset:", descriptor, offset)
|
return msgSend(^Texture, self, "newTextureWithDescriptor:offset:", descriptor, offset)
|
||||||
}
|
}
|
||||||
@(objc_type=Heap, objc_name="resourceOptions")
|
@(objc_type=Heap, objc_name="resourceOptions")
|
||||||
Heap_resourceOptions :: #force_inline proc(self: ^Heap) -> ResourceOptions {
|
Heap_resourceOptions :: #force_inline proc(self: ^Heap) -> ResourceOptions {
|
||||||
|
|||||||
Reference in New Issue
Block a user