Livt packages
Livt.Crypto
Version 1.0.5
Fixed-size cryptographic components for Livt, including AES, ChaCha20, SHA, MACs, and key derivation.
Published files (69)
src/hash/Sha3512.lvt
namespace Livt.Crypto.Hash
using Livt.Crypto.Internal
// SHA-3-512 (NIST FIPS 202) — Keccak-based hash, 512-bit output.
//
// Parameters: rate = 72 bytes, capacity = 128 bytes, output = 64 bytes.
// Domain separation suffix: 0x06.
//
// Usage:
// 1. Reset() — clear state for a new message
// 2. ProcessBlock(msg: byte[72]) — absorb one rate-sized block (before padding)
// Repeat step 2 for each full 72-byte block.
// 3. Finalize(lastBlock, lastLen) — absorb the final partial block with padding
// 4. GetDigest() byte[64] — read first 64 bytes of squeezed output
//
// The caller applies SHA-3 domain suffix (0x06) and Keccak padding via Finalize.
component Sha3512
{
public const BLOCK_SIZE: int = 72 // rate = 1600 - 1024 bits = 72 bytes
public const DIGEST_SIZE: int = 64
keccak: Keccak
new()
{
this.keccak = new Keccak()
}
// -----------------------------------------------------------------------
// Public API
// -----------------------------------------------------------------------
// Reset: initialise state for a new hash.
public fn Reset()
{
this.keccak.Reset()
}
// ProcessBlock: absorb one full 72-byte rate block.
public fn ProcessBlock(msg: byte[72])
{
var buf: byte[200]
for (var i = 0; i < 72; i++)
{
buf[i] = msg[i]
}
this.keccak.XorBytes(buf, 72)
this.keccak.Permute()
}
// Finalize: absorb the last partial block (lastLen bytes of lastBlock),
// apply SHA-3 padding (0x06 at lastLen, 0x80 at byte 71), then permute.
// lastLen must be in [0, 71].
public fn Finalize(lastBlock: byte[72], lastLen: int)
{
var buf: byte[200]
for (var i = 0; i < lastLen; i++)
{
buf[i] = lastBlock[i]
}
buf[lastLen] = 0x06
buf[71] = 0x80
// If lastLen == 71, 0x06 and 0x80 are at the same byte → XOR = 0x86.
if (lastLen == 71)
{
buf[71] = 0x86
}
this.keccak.XorBytes(buf, 72)
this.keccak.Permute()
}
// GetDigest: return first 64 bytes (512 bits) of state as digest.
public fn GetDigest() byte[64]
{
var digest: byte[64]
for (var i = 0; i < 64; i++)
{
var bi: byte = this.keccak.GetByte(i)
digest[i] = bi
}
return digest
}
}