From 420f296ca5ff52ee3852c2a28b527e73b35f256a Mon Sep 17 00:00:00 2001 From: Toni Date: Sun, 4 Jan 2026 10:25:54 +0100 Subject: [PATCH] split crypto from std once again --- src/main.rs | 7 +- src/std/crypto.zr | 288 ++++++++++++++++++++++++++++++++++++++++++ src/{ => std}/std.zr | 291 +------------------------------------------ 3 files changed, 295 insertions(+), 291 deletions(-) create mode 100644 src/std/crypto.zr rename src/{ => std}/std.zr (63%) diff --git a/src/main.rs b/src/main.rs index db6ea66..895c10b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -64,7 +64,12 @@ fn compile_file(args: Args) -> Result<(), ZernError> { let mut analyzer = analyzer::Analyzer::new(); let mut codegen = codegen_x86_64::CodegenX86_64::new(&mut analyzer); codegen.emit_prologue()?; - compile_file_to(&mut codegen, "std.zr", include_str!("std.zr").into())?; + compile_file_to(&mut codegen, "std.zr", include_str!("std/std.zr").into())?; + compile_file_to( + &mut codegen, + "crypto.zr", + include_str!("std/crypto.zr").into(), + )?; compile_file_to(&mut codegen, filename, source)?; if !args.output_asm { diff --git a/src/std/crypto.zr b/src/std/crypto.zr new file mode 100644 index 0000000..76218ea --- /dev/null +++ b/src/std/crypto.zr @@ -0,0 +1,288 @@ +func crypto.rotl32[x: i64, r: i64] : i64 + return ((x << r) | (x >> (32 - r))) & 0xffffffff + +func crypto.chacha20._quarter_round[state: ptr, a: i64, b: i64, c: i64, d: i64] : void + let va: i64 = mem.read32(state + a * 4) + let vb: i64 = mem.read32(state + b * 4) + let vc: i64 = mem.read32(state + c * 4) + let vd: i64 = mem.read32(state + d * 4) + va = (va + vb) & 0xffffffff + vd = vd ^ va + vd = crypto.rotl32(vd, 16) + vc = (vc + vd) & 0xffffffff + vb = vb ^ vc + vb = crypto.rotl32(vb, 12) + va = (va + vb) & 0xffffffff + vd = vd ^ va + vd = crypto.rotl32(vd, 8) + vc = (vc + vd) & 0xffffffff + vb = vb ^ vc + vb = crypto.rotl32(vb, 7) + mem.write32(state + a * 4, va) + mem.write32(state + b * 4, vb) + mem.write32(state + c * 4, vc) + mem.write32(state + d * 4, vd) + +func crypto.xchacha20._permute[state: ptr] : void + for i in 0..10 + crypto.chacha20._quarter_round(state, 0, 4, 8, 12) + crypto.chacha20._quarter_round(state, 1, 5, 9, 13) + crypto.chacha20._quarter_round(state, 2, 6, 10, 14) + crypto.chacha20._quarter_round(state, 3, 7, 11, 15) + crypto.chacha20._quarter_round(state, 0, 5, 10, 15) + crypto.chacha20._quarter_round(state, 1, 6, 11, 12) + crypto.chacha20._quarter_round(state, 2, 7, 8, 13) + crypto.chacha20._quarter_round(state, 3, 4, 9, 14) + +func crypto.xchacha20._block[key: ptr, nonce: ptr, blocknum: i64, out: ptr] : void + let sigma: str = "expand 32-byte k" + let state: ptr = mem.alloc(16 * 4) + + mem.write32(state + 0, mem.read32(sigma + 0)) + mem.write32(state + 4, mem.read32(sigma + 4)) + mem.write32(state + 8, mem.read32(sigma + 8)) + mem.write32(state + 12, mem.read32(sigma + 12)) + + for i in 0..8 + mem.write32(state + (4 + i) * 4, mem.read32(key + i * 4)) + + mem.write32(state + 12 * 4, blocknum) + mem.write32(state + 13 * 4, mem.read32(nonce + 0)) + mem.write32(state + 14 * 4, mem.read32(nonce + 4)) + mem.write32(state + 15 * 4, mem.read32(nonce + 8)) + + let working: ptr = mem.alloc(16 * 4) + for i in 0..16 + mem.write32(working + i * 4, mem.read32(state + i * 4)) + + crypto.xchacha20._permute(working) + + for i in 0..16 + let v: i64 = (mem.read32(working + i * 4) + mem.read32(state + i * 4)) & 0xffffffff + mem.write32(out + i * 4, v) + mem.free(working) + mem.free(state) + +func crypto.xchacha20._hchacha20[key: ptr, input: ptr, out32: ptr] : void + let sigma: str = "expand 32-byte k" + let state: ptr = mem.alloc(16 * 4) + + mem.write32(state + 0, mem.read32(sigma + 0)) + mem.write32(state + 4, mem.read32(sigma + 4)) + mem.write32(state + 8, mem.read32(sigma + 8)) + mem.write32(state + 12, mem.read32(sigma + 12)) + + for i in 0..8 + mem.write32(state + (4 + i) * 4, mem.read32(key + i * 4)) + + for i in 0..4 + mem.write32(state + (12 + i) * 4, mem.read32(input + i * 4)) + + crypto.xchacha20._permute(state) + + for i in 0..4 + mem.write32(out32 + i * 4, mem.read32(state + i * 4)) + for i in 0..4 + mem.write32(out32 + 16 + i * 4, mem.read32(state + (12 + i) * 4)) + mem.free(state) + +func crypto.xchacha20._stream[key: ptr, nonce: ptr, out: ptr, len: i64] : void + let subkey: ptr = mem.alloc(32) + crypto.xchacha20._hchacha20(key, nonce, subkey) + + let nonce12: ptr = mem.alloc(12) + for i in 0..12 + mem.write8(nonce12 + i, 0) + for i in 0..8 + mem.write8(nonce12 + 4 + i, nonce[16 + i]) + + let blocknum: i64 = 0 + let remaining: i64 = len + let block: ptr = mem.alloc(64) + + while remaining > 0 + crypto.xchacha20._block(subkey, nonce12, blocknum, block) + let take: i64 = 64 + if remaining < 64 + take = remaining + for i in 0..take + mem.write8(out + (len - remaining) + i, block[i]) + remaining = remaining - take + blocknum = blocknum + 1 + mem.free(block) + mem.free(nonce12) + mem.free(subkey) + +func crypto.xchacha20.xor[key: ptr, nonce: ptr, input: ptr, len: i64] : ptr + if len <= 0 + return dbg.panic("empty buffer passed to crypto.xchacha20.xor") + let out: ptr = mem.alloc(len) + let ks: ptr = mem.alloc(len) + crypto.xchacha20._stream(key, nonce, ks, len) + for i in 0..len + mem.write8(out + i, input[i] ^ ks[i]) + mem.free(ks) + return out + +func crypto.x25519.carry[elem: ptr] : void + for i in 0..16 + let carry: i64 = mem.read64(elem + i * 8) >> 16 + mem.write64(elem + i * 8, mem.read64(elem + i * 8) - (carry << 16)) + if i < 15 + mem.write64(elem + (i + 1) * 8, mem.read64(elem + (i + 1) * 8) + carry) + else + mem.write64(elem, mem.read64(elem) + 38 * carry) + +func crypto.x25519.fadd[out: ptr, a: ptr, b: ptr] : void + for i in 0..16 + mem.write64(out + i * 8, mem.read64(a + i * 8) + mem.read64(b + i * 8)) + +func crypto.x25519.fsub[out: ptr, a: ptr, b: ptr] : void + for i in 0..16 + mem.write64(out + i * 8, mem.read64(a + i * 8) - mem.read64(b + i * 8)) + +func crypto.x25519.fmul[out: ptr, a: ptr, b: ptr] : void + let product: ptr = mem.alloc(31 * 8) + for i in 0..31 + mem.write64(product + i * 8, 0) + for i in 0..16 + for j in 0..16 + mem.write64(product + (i + j) * 8, mem.read64(product + (i + j) * 8) + (mem.read64(a + i * 8) * mem.read64(b + j * 8))) + for i in 0..15 + mem.write64(product + i * 8, mem.read64(product + i * 8) + 38 * mem.read64(product + (i + 16) * 8)) + for i in 0..16 + mem.write64(out + i * 8, mem.read64(product + i * 8)) + + crypto.x25519.carry(out) + crypto.x25519.carry(out) + mem.free(product) + +func crypto.x25519.finverse[out: ptr, input: ptr] : void + let c: ptr = mem.alloc(16 * 8) + for i in 0..16 + mem.write64(c + i * 8, mem.read64(input + i * 8)) + + let i = 253 + while i >= 0 + crypto.x25519.fmul(c, c, c) + if i != 2 && i != 4 + crypto.x25519.fmul(c, c, input) + i = i - 1 + + for i in 0..16 + mem.write64(out + i * 8, mem.read64(c + i * 8)) + mem.free(c) + +func crypto.x25519.swap[p: ptr, q: ptr, bit: i64] : void + for i in 0..16 + let t: i64 = (-bit) & (mem.read64(p + i * 8) ^ mem.read64(q + i * 8)) + mem.write64(p + i * 8, mem.read64(p + i * 8) ^ t) + mem.write64(q + i * 8, mem.read64(q + i * 8) ^ t) + +func crypto.x25519.unpack[out: ptr, input: ptr] : void + for i in 0..16 + mem.write64(out + i * 8, input[i * 2] + (input[i * 2 + 1] << 8)) + mem.write64(out + 8 * 15, mem.read64(out + 8 * 15) & 0x7fff) + +func crypto.x25519.pack[out: ptr, input: ptr] : void + let t: ptr = mem.alloc(16 * 8) + for i in 0..16 + mem.write64(t + i * 8, mem.read64(input + i * 8)) + let m: ptr = mem.alloc(16 * 8) + + crypto.x25519.carry(t) + crypto.x25519.carry(t) + crypto.x25519.carry(t) + for j in 0..2 + mem.write64(m, mem.read64(t) - 0xffed) + for i in 1..15 + mem.write64(m + i * 8, mem.read64(t + i * 8) - 0xffff - ((mem.read64(m + (i - 1) * 8) >> 16) & 1)) + mem.write64(m + (i - 1) * 8, mem.read64(m + (i - 1) * 8) & 0xffff) + mem.write64(m + 15 * 8, mem.read64(t + 15 * 8) - 0x7fff - ((mem.read64(m + 14 * 8) >> 16) & 1)) + let carry: i64 = (mem.read64(m + 15 * 8) >> 16) & 1 + mem.write64(m + 14 * 8, mem.read64(m + 14 * 8) & 0xffff) + crypto.x25519.swap(t, m, 1 - carry) + + for i in 0..16 + let v: i64 = mem.read64(t + i * 8) + mem.write8(out + i * 2, v & 0xff) + mem.write8(out + i * 2 + 1, (v >> 8) & 0xff) + + mem.free(t) + mem.free(m) + +func crypto.x25519.scalarmult[scalar: ptr, point: ptr] : ptr + let clamped: ptr = mem.alloc(32) + let a: ptr = mem.alloc(16 * 8) + let b: ptr = mem.alloc(16 * 8) + let c: ptr = mem.alloc(16 * 8) + let d: ptr = mem.alloc(16 * 8) + let e: ptr = mem.alloc(16 * 8) + let f: ptr = mem.alloc(16 * 8) + let x: ptr = mem.alloc(16 * 8) + + let magic: ptr = mem.alloc(16 * 8) + mem.zero(magic, 16 * 8) + mem.write64(magic, 0xdb41) // 121665 + mem.write64(magic + 8, 1) + + // copy and clamp scalar + for i in 0..32 + mem.write8(clamped + i, scalar[i]) + mem.write8(clamped, clamped[0] & 0xf8) + mem.write8(clamped + 31, (clamped[31] & 0x7f) | 0x40) + + // load point + crypto.x25519.unpack(x, point) + + // initialize ladder state + for i in 0..16 + mem.write64(a + i * 8, 0) + mem.write64(b + i * 8, mem.read64(x + i * 8)) + mem.write64(c + i * 8, 0) + mem.write64(d + i * 8, 0) + mem.write64(a, 1) + mem.write64(d, 1) + + let i = 254 + while i >= 0 + let bit: i64 = (clamped[i >> 3] >> (i & 7)) & 1 + crypto.x25519.swap(a, b, bit) + crypto.x25519.swap(c, d, bit) + crypto.x25519.fadd(e, a, c) + crypto.x25519.fsub(a, a, c) + crypto.x25519.fadd(c, b, d) + crypto.x25519.fsub(b, b, d) + crypto.x25519.fmul(d, e, e) + crypto.x25519.fmul(f, a, a) + crypto.x25519.fmul(a, c, a) + crypto.x25519.fmul(c, b, e) + crypto.x25519.fadd(e, a, c) + crypto.x25519.fsub(a, a, c) + crypto.x25519.fmul(b, a, a) + crypto.x25519.fsub(c, d, f) + crypto.x25519.fmul(a, c, magic) + crypto.x25519.fadd(a, a, d) + crypto.x25519.fmul(c, c, a) + crypto.x25519.fmul(a, d, f) + crypto.x25519.fmul(d, b, x) + crypto.x25519.fmul(b, e, e) + crypto.x25519.swap(a, b, bit) + crypto.x25519.swap(c, d, bit) + i = i - 1 + + crypto.x25519.finverse(c, c) + crypto.x25519.fmul(a, a, c) + let out: ptr = mem.alloc(32) + crypto.x25519.pack(out, a) + + mem.free(clamped) + mem.free(a) + mem.free(b) + mem.free(c) + mem.free(d) + mem.free(e) + mem.free(f) + mem.free(x) + mem.free(magic) + return out \ No newline at end of file diff --git a/src/std.zr b/src/std/std.zr similarity index 63% rename from src/std.zr rename to src/std/std.zr index 015a75a..46748df 100644 --- a/src/std.zr +++ b/src/std/std.zr @@ -664,293 +664,4 @@ func net.close[s: i64] : void _builtin_syscall(3, s) func net.pack_addr[a: i64, b: i64, c: i64, d: i64] : i64 - return (a << 24) | (b << 16) | (c << 8) | d - -func crypto.rotl32[x: i64, r: i64] : i64 - return ((x << r) | (x >> (32 - r))) & 0xffffffff - -func crypto.chacha20._quarter_round[state: ptr, a: i64, b: i64, c: i64, d: i64] : void - let va: i64 = mem.read32(state + a * 4) - let vb: i64 = mem.read32(state + b * 4) - let vc: i64 = mem.read32(state + c * 4) - let vd: i64 = mem.read32(state + d * 4) - va = (va + vb) & 0xffffffff - vd = vd ^ va - vd = crypto.rotl32(vd, 16) - vc = (vc + vd) & 0xffffffff - vb = vb ^ vc - vb = crypto.rotl32(vb, 12) - va = (va + vb) & 0xffffffff - vd = vd ^ va - vd = crypto.rotl32(vd, 8) - vc = (vc + vd) & 0xffffffff - vb = vb ^ vc - vb = crypto.rotl32(vb, 7) - mem.write32(state + a * 4, va) - mem.write32(state + b * 4, vb) - mem.write32(state + c * 4, vc) - mem.write32(state + d * 4, vd) - -func crypto.xchacha20._permute[state: ptr] : void - for i in 0..10 - crypto.chacha20._quarter_round(state, 0, 4, 8, 12) - crypto.chacha20._quarter_round(state, 1, 5, 9, 13) - crypto.chacha20._quarter_round(state, 2, 6, 10, 14) - crypto.chacha20._quarter_round(state, 3, 7, 11, 15) - crypto.chacha20._quarter_round(state, 0, 5, 10, 15) - crypto.chacha20._quarter_round(state, 1, 6, 11, 12) - crypto.chacha20._quarter_round(state, 2, 7, 8, 13) - crypto.chacha20._quarter_round(state, 3, 4, 9, 14) - -func crypto.xchacha20._block[key: ptr, nonce: ptr, blocknum: i64, out: ptr] : void - let sigma: str = "expand 32-byte k" - let state: ptr = mem.alloc(16 * 4) - - mem.write32(state + 0, mem.read32(sigma + 0)) - mem.write32(state + 4, mem.read32(sigma + 4)) - mem.write32(state + 8, mem.read32(sigma + 8)) - mem.write32(state + 12, mem.read32(sigma + 12)) - - for i in 0..8 - mem.write32(state + (4 + i) * 4, mem.read32(key + i * 4)) - - mem.write32(state + 12 * 4, blocknum) - mem.write32(state + 13 * 4, mem.read32(nonce + 0)) - mem.write32(state + 14 * 4, mem.read32(nonce + 4)) - mem.write32(state + 15 * 4, mem.read32(nonce + 8)) - - let working: ptr = mem.alloc(16 * 4) - for i in 0..16 - mem.write32(working + i * 4, mem.read32(state + i * 4)) - - crypto.xchacha20._permute(working) - - for i in 0..16 - let v: i64 = (mem.read32(working + i * 4) + mem.read32(state + i * 4)) & 0xffffffff - mem.write32(out + i * 4, v) - mem.free(working) - mem.free(state) - -func crypto.xchacha20._hchacha20[key: ptr, input: ptr, out32: ptr] : void - let sigma: str = "expand 32-byte k" - let state: ptr = mem.alloc(16 * 4) - - mem.write32(state + 0, mem.read32(sigma + 0)) - mem.write32(state + 4, mem.read32(sigma + 4)) - mem.write32(state + 8, mem.read32(sigma + 8)) - mem.write32(state + 12, mem.read32(sigma + 12)) - - for i in 0..8 - mem.write32(state + (4 + i) * 4, mem.read32(key + i * 4)) - - for i in 0..4 - mem.write32(state + (12 + i) * 4, mem.read32(input + i * 4)) - - crypto.xchacha20._permute(state) - - for i in 0..4 - mem.write32(out32 + i * 4, mem.read32(state + i * 4)) - for i in 0..4 - mem.write32(out32 + 16 + i * 4, mem.read32(state + (12 + i) * 4)) - mem.free(state) - -func crypto.xchacha20._stream[key: ptr, nonce: ptr, out: ptr, len: i64] : void - let subkey: ptr = mem.alloc(32) - crypto.xchacha20._hchacha20(key, nonce, subkey) - - let nonce12: ptr = mem.alloc(12) - for i in 0..12 - mem.write8(nonce12 + i, 0) - for i in 0..8 - mem.write8(nonce12 + 4 + i, nonce[16 + i]) - - let blocknum: i64 = 0 - let remaining: i64 = len - let block: ptr = mem.alloc(64) - - while remaining > 0 - crypto.xchacha20._block(subkey, nonce12, blocknum, block) - let take: i64 = 64 - if remaining < 64 - take = remaining - for i in 0..take - mem.write8(out + (len - remaining) + i, block[i]) - remaining = remaining - take - blocknum = blocknum + 1 - mem.free(block) - mem.free(nonce12) - mem.free(subkey) - -func crypto.xchacha20.xor[key: ptr, nonce: ptr, input: ptr, len: i64] : ptr - if len <= 0 - return dbg.panic("empty buffer passed to crypto.xchacha20.xor") - let out: ptr = mem.alloc(len) - let ks: ptr = mem.alloc(len) - crypto.xchacha20._stream(key, nonce, ks, len) - for i in 0..len - mem.write8(out + i, input[i] ^ ks[i]) - mem.free(ks) - return out - -func crypto.x25519.carry[elem: ptr] : void - for i in 0..16 - let carry: i64 = mem.read64(elem + i * 8) >> 16 - mem.write64(elem + i * 8, mem.read64(elem + i * 8) - (carry << 16)) - if i < 15 - mem.write64(elem + (i + 1) * 8, mem.read64(elem + (i + 1) * 8) + carry) - else - mem.write64(elem, mem.read64(elem) + 38 * carry) - -func crypto.x25519.fadd[out: ptr, a: ptr, b: ptr] : void - for i in 0..16 - mem.write64(out + i * 8, mem.read64(a + i * 8) + mem.read64(b + i * 8)) - -func crypto.x25519.fsub[out: ptr, a: ptr, b: ptr] : void - for i in 0..16 - mem.write64(out + i * 8, mem.read64(a + i * 8) - mem.read64(b + i * 8)) - -func crypto.x25519.fmul[out: ptr, a: ptr, b: ptr] : void - let product: ptr = mem.alloc(31 * 8) - for i in 0..31 - mem.write64(product + i * 8, 0) - for i in 0..16 - for j in 0..16 - mem.write64(product + (i + j) * 8, mem.read64(product + (i + j) * 8) + (mem.read64(a + i * 8) * mem.read64(b + j * 8))) - for i in 0..15 - mem.write64(product + i * 8, mem.read64(product + i * 8) + 38 * mem.read64(product + (i + 16) * 8)) - for i in 0..16 - mem.write64(out + i * 8, mem.read64(product + i * 8)) - - crypto.x25519.carry(out) - crypto.x25519.carry(out) - mem.free(product) - -func crypto.x25519.finverse[out: ptr, input: ptr] : void - let c: ptr = mem.alloc(16 * 8) - for i in 0..16 - mem.write64(c + i * 8, mem.read64(input + i * 8)) - - let i = 253 - while i >= 0 - crypto.x25519.fmul(c, c, c) - if i != 2 && i != 4 - crypto.x25519.fmul(c, c, input) - i = i - 1 - - for i in 0..16 - mem.write64(out + i * 8, mem.read64(c + i * 8)) - mem.free(c) - -func crypto.x25519.swap[p: ptr, q: ptr, bit: i64] : void - for i in 0..16 - let t: i64 = (-bit) & (mem.read64(p + i * 8) ^ mem.read64(q + i * 8)) - mem.write64(p + i * 8, mem.read64(p + i * 8) ^ t) - mem.write64(q + i * 8, mem.read64(q + i * 8) ^ t) - -func crypto.x25519.unpack[out: ptr, input: ptr] : void - for i in 0..16 - mem.write64(out + i * 8, input[i * 2] + (input[i * 2 + 1] << 8)) - mem.write64(out + 8 * 15, mem.read64(out + 8 * 15) & 0x7fff) - -func crypto.x25519.pack[out: ptr, input: ptr] : void - let t: ptr = mem.alloc(16 * 8) - for i in 0..16 - mem.write64(t + i * 8, mem.read64(input + i * 8)) - let m: ptr = mem.alloc(16 * 8) - - crypto.x25519.carry(t) - crypto.x25519.carry(t) - crypto.x25519.carry(t) - for j in 0..2 - mem.write64(m, mem.read64(t) - 0xffed) - for i in 1..15 - mem.write64(m + i * 8, mem.read64(t + i * 8) - 0xffff - ((mem.read64(m + (i - 1) * 8) >> 16) & 1)) - mem.write64(m + (i - 1) * 8, mem.read64(m + (i - 1) * 8) & 0xffff) - mem.write64(m + 15 * 8, mem.read64(t + 15 * 8) - 0x7fff - ((mem.read64(m + 14 * 8) >> 16) & 1)) - let carry: i64 = (mem.read64(m + 15 * 8) >> 16) & 1 - mem.write64(m + 14 * 8, mem.read64(m + 14 * 8) & 0xffff) - crypto.x25519.swap(t, m, 1 - carry) - - for i in 0..16 - let v: i64 = mem.read64(t + i * 8) - mem.write8(out + i * 2, v & 0xff) - mem.write8(out + i * 2 + 1, (v >> 8) & 0xff) - - mem.free(t) - mem.free(m) - -func crypto.x25519.scalarmult[scalar: ptr, point: ptr] : ptr - let clamped: ptr = mem.alloc(32) - let a: ptr = mem.alloc(16 * 8) - let b: ptr = mem.alloc(16 * 8) - let c: ptr = mem.alloc(16 * 8) - let d: ptr = mem.alloc(16 * 8) - let e: ptr = mem.alloc(16 * 8) - let f: ptr = mem.alloc(16 * 8) - let x: ptr = mem.alloc(16 * 8) - - let magic: ptr = mem.alloc(16 * 8) - mem.zero(magic, 16 * 8) - mem.write64(magic, 0xdb41) // 121665 - mem.write64(magic + 8, 1) - - // copy and clamp scalar - for i in 0..32 - mem.write8(clamped + i, scalar[i]) - mem.write8(clamped, clamped[0] & 0xf8) - mem.write8(clamped + 31, (clamped[31] & 0x7f) | 0x40) - - // load point - crypto.x25519.unpack(x, point) - - // initialize ladder state - for i in 0..16 - mem.write64(a + i * 8, 0) - mem.write64(b + i * 8, mem.read64(x + i * 8)) - mem.write64(c + i * 8, 0) - mem.write64(d + i * 8, 0) - mem.write64(a, 1) - mem.write64(d, 1) - - let i = 254 - while i >= 0 - let bit: i64 = (clamped[i >> 3] >> (i & 7)) & 1 - crypto.x25519.swap(a, b, bit) - crypto.x25519.swap(c, d, bit) - crypto.x25519.fadd(e, a, c) - crypto.x25519.fsub(a, a, c) - crypto.x25519.fadd(c, b, d) - crypto.x25519.fsub(b, b, d) - crypto.x25519.fmul(d, e, e) - crypto.x25519.fmul(f, a, a) - crypto.x25519.fmul(a, c, a) - crypto.x25519.fmul(c, b, e) - crypto.x25519.fadd(e, a, c) - crypto.x25519.fsub(a, a, c) - crypto.x25519.fmul(b, a, a) - crypto.x25519.fsub(c, d, f) - crypto.x25519.fmul(a, c, magic) - crypto.x25519.fadd(a, a, d) - crypto.x25519.fmul(c, c, a) - crypto.x25519.fmul(a, d, f) - crypto.x25519.fmul(d, b, x) - crypto.x25519.fmul(b, e, e) - crypto.x25519.swap(a, b, bit) - crypto.x25519.swap(c, d, bit) - i = i - 1 - - crypto.x25519.finverse(c, c) - crypto.x25519.fmul(a, a, c) - let out: ptr = mem.alloc(32) - crypto.x25519.pack(out, a) - - mem.free(clamped) - mem.free(a) - mem.free(b) - mem.free(c) - mem.free(d) - mem.free(e) - mem.free(f) - mem.free(x) - mem.free(magic) - return out \ No newline at end of file + return (a << 24) | (b << 16) | (c << 8) | d \ No newline at end of file