Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
637 changes: 637 additions & 0 deletions lib/src/crypto/argon2id.valk

Large diffs are not rendered by default.

20 changes: 19 additions & 1 deletion lib/src/crypto/blake2b.valk
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

use mem

value BLAKE2B_OUTBYTES (64)

+ macro ROR64 "(" V:word "," V:shift ")" <{
return (word >> shift) | (word << (64 - shift))
}
Expand Down Expand Up @@ -51,6 +53,7 @@ macro LOAD64LE "(" V:val ")" <{
buf: [u8 x 128] ([0 ...])
buf_len: uint (0)
hash_size: uint
key: ?String

+ static fn hash_str(input: String, key: ?String (null), lowercase: bool (true)) String !invalid_key {
let result : [u8 x 64] = [0...]
Expand Down Expand Up @@ -88,7 +91,7 @@ macro LOAD64LE "(" V:val ")" <{
let state : [u64 x 8] = IV
state[0] = state[0] ^ (hash_size.to(u64) | (keylen << 8) | (1 << 16) | (1 << 24))

let b = Blake2b { h: state, hash_size: hash_size }
let b = Blake2b { h: state, hash_size: hash_size, key: key }

// Secret key
if isset(key) {
Expand All @@ -99,6 +102,21 @@ macro LOAD64LE "(" V:val ")" <{
return b
}

// + fn reset() {
// let keylen = 0
// let key = this.key
// if isset(key) : keylen = key.length
// //
// let state : [u64 x 8] = IV
// state[0] = state[0] ^ (this.hash_size.to(u64) | (keylen << 8) | (1 << 16) | (1 << 24))
// this.h = state
// //
// if isset(key) {
// mem:copy(key.data, this.buf, keylen);
// this.buf_len = 128;
// }
// }

+ fn update(data: ptr[u8], length: uint) {

let n = 0
Expand Down
36 changes: 36 additions & 0 deletions lib/src/type/number.valk
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,40 @@ global num2str_buf2 : ?ptr (@undefined)
#end
return this == v
}

+ static fn write_little_endian(v: SELF, to: ptr[u8 x size_of(SELF)]) {
let i = 0
while i < size_of(SELF) {
to[i++] = (v & 0xFF).to(u8)
v = v >> 1
}
}
+ static fn write_big_endian(v: SELF, to: ptr[u8 x size_of(SELF)]) {
let i = size_of(SELF)
while i-- > 0 {
to[i] = (v & 0xFF).to(u8)
v = v >> 8
}
}

+ static fn read_little_endian(from: ptr[u8 x size_of(SELF)]) SELF {
let v : SELF = 0
let sh : SELF = 0
let i = 0
while i < size_of(SELF) {
v = v | (from[i++].to(SELF) << sh)
sh += 8
}
return v
}
+ static fn read_big_endian(from: ptr[u8 x size_of(SELF)]) SELF {
let v : SELF = 0
let sh : SELF = 0
let i = size_of(SELF)
while i-- > 0 {
v = v | (from[i++].to(SELF) << sh)
sh += 8
}
return v
}
}
5 changes: 4 additions & 1 deletion src/build/ast.valk
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ fn read_ast(p: Parser, scope: Scope, single: bool) {

t = p.tok(true, true, false)
if t == tok_sign {
if p.word_is("=") || p.word_is("+=") || p.word_is("-=") || p.word_is("*=") || p.word_is("/=") || p.word_is("%=") {
if p.word_is("=") || p.word_is("+=") || p.word_is("-=") || p.word_is("*=") || p.word_is("/=") || p.word_is("%=") || p.word_is("^=") || p.word_is("&=") || p.word_is("|=") {
t = p.tok(true, true)

let assign_chunk = p.clone_chunk()
Expand All @@ -119,6 +119,9 @@ fn read_ast(p: Parser, scope: Scope, single: bool) {
else if p.word_is("*=") : op = op_mul
else if p.word_is("/=") : op = op_div
else if p.word_is("%=") : op = op_mod
else if p.word_is("^=") : op = op_bit_xor
else if p.word_is("&=") : op = op_bit_and
else if p.word_is("|=") : op = op_bit_or

p.set_suggest(left.rett)
let right = read_value(p, scope)
Expand Down
13 changes: 13 additions & 0 deletions src/build/offset.valk
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@ fn parse_offset_value(p: Parser, scope: Scope, on: Value) Value {
p.error("Out of bounds. You are asking for index '" + index.int + "' on type: " + array_type + ". The last index is: " + (max_offset - 1))
}

// if p.next_word_is("...", true, true, true) {
// let new_offset = max_offset - index.int
// let indexv = vgen_int(new_offset * sub.size(), p.build.valk_type("type", "int"))
// let result = vgen_ptr_offset(on, indexv)
// let rett = on.rett.clone()
// let atype = array_type.clone()
// atype.array_size = new_offset
// rett.sub_type = atype
// result.rett = rett
// p.expect("]", true, true)
// return result
// }

// Result
let result = vgen_ptrv(on, sub, index)
p.expect("]", true, true)
Expand Down
7 changes: 5 additions & 2 deletions src/build/parser.valk
Original file line number Diff line number Diff line change
Expand Up @@ -201,13 +201,16 @@ class Parser {
} else if ch == '/' && (next == '=') {
this.i++
this.col++
} else if ch == '^' && (next == '=') {
this.i++
this.col++
} else if ch == '?' && (next == '?' || next == '!') {
this.i++
this.col++
} else if ch == '&' && (next == '&') {
} else if ch == '&' && (next == '&' || next == '=') {
this.i++
this.col++
} else if ch == '|' && (next == '|') {
} else if ch == '|' && (next == '|' || next == '=') {
this.i++
this.col++
} else if ch == '.' && next == '.' && @ptrv(data, u8, this.i + 1) == '.' {
Expand Down
8 changes: 4 additions & 4 deletions src/build/stage-2-4-types.valk
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ fn stage_types(b: Build) {

if b.verbose > 2 : b.log("> Stage 2.4: Read types for functions & globals")

each b.enums as e {
await (co parse_enum_type(e)) ! continue
}

each b.units as unit {
each unit.functions as func {
await (co parse_func_args(func)) ! continue
Expand All @@ -15,10 +19,6 @@ fn stage_types(b: Build) {
await (co parse_global_type(g)) ! continue
}

each b.enums as e {
await (co parse_enum_type(e)) ! continue
}

each b.classes as class {
await (co class.validate_internals()) ! continue
}
Expand Down
20 changes: 15 additions & 5 deletions src/build/type.valk
Original file line number Diff line number Diff line change
Expand Up @@ -315,11 +315,13 @@ class Type {
let sub = base.sub_type
if !type.is_pointer : return false
if isset(sub) {
let sub2 = type.get_inline()
if sub.type == ty_array && sub2.type != ty_array {
sub2 = type_array(base.build, sub2, 1)
let sub2 = type.sub_type
if isset(sub2) {
if sub.type == ty_array && sub2.type != ty_array {
sub2 = type_array(base.build, sub2, 1)
}
return sub.compat(sub2, ignore_imut)
}
return sub.compat(sub2, ignore_imut)
}
return true
}
Expand Down Expand Up @@ -708,7 +710,15 @@ fn handle_type_idf(p: Parser, scope: Scope, idf: Idf) Type {
if !isset(prop) : p.bug("Missing property info for identifier")
return prop.type
}
// TODO: Enums
if for == idf_enum {
let enum = idf.enum
if !isset(enum) : p.bug("Missing enum info for enum identifier")
let type = enum.type
if !isset(type) : p.bug("Missing enum value-type for enum identifier")
let t = type.clone()
t.enum = enum
return t
}

p.error("Not a type")
}
Expand Down
10 changes: 8 additions & 2 deletions src/build/value.valk
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,7 @@ fn read_value(p: Parser, scope: Scope, prio: int (99999), assignable: bool (fals
p.expect(")", true, true)

v = vgen_ref(on)
v.rett.type = ty_ptr

} else if p.word_is("@global_default_value") {
p.expect("(", false, false)
Expand Down Expand Up @@ -1979,7 +1980,7 @@ fn handle_enum(p: Parser, e: Enum, scope: Scope) Value {
let values = e.values
let chunk = values.get(name) ! p.error("Enum " + e.display_name + " does not have a value named: '" + name + "'")
let type = e.type
if !isset(type) : p.error("Missing enum type (bug)")
if !isset(type) : p.bug("Missing enum type")
if isset(chunk) {
let fc = e.fc
let escope = fc.scope
Expand All @@ -1991,6 +1992,7 @@ fn handle_enum(p: Parser, e: Enum, scope: Scope) Value {
sp.pop_suggest()
let rett = v.rett.clone()
rett.enum = e
v.rett = rett
return v
}

Expand All @@ -2003,7 +2005,11 @@ fn handle_enum(p: Parser, e: Enum, scope: Scope) Value {
}
}
let intv = e.values_int.get(name) ! p.error("Missing integer value for enum item (bug)")
return vgen_int(intv, int_type)
let v = vgen_int(intv, int_type)
let rett = v.rett.clone()
rett.enum = e
v.rett = rett
return v
}


Expand Down
16 changes: 16 additions & 0 deletions tests/crypto-argon2.valk
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

use valk:crypto

test "Blake2b" {

// Without key
let hash = crypto:Argon2.hash_str("abc") !? "failed"
assert(hash == "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923")
// With key
hash = crypto:Argon2.hash_str("abc", "test") !? "failed"
assert(hash == "271aafa177d01c1a96b5db53cacf75fc895f757f3a24cfbacb07d2d737bcf6997dbcf8b2e97bace9842f526208197791996f9d5c557124d2ce3353bf0e263339")
// Long input
hash = crypto:Argon2.hash_str("abcabcabcabcabcabc123456789abcabcabcabcabcabc123456789") !? "failed"
assert(hash == "b6d52f42f810a7b8e8b0e9d794d2aa8dd1f3bda927511045a9efeefb1a8d0f9b26f720da1b0b884ce015375b6fc18a842f84a07e78d457f203046b67fff28489")

}
File renamed without changes.
Loading