download
raw
4.96 kB
import { rotl64 } from "@oslojs/binary";
export class SHA3 {
rate;
outputSize;
state = new BigUint64Array(25);
absorbedBytes = 0;
constructor(rate, outputSize) {
this.rate = rate;
this.outputSize = outputSize;
}
absorb(bytes) {
for (let i = 0; i < bytes.byteLength; i++) {
this.state[Math.floor(this.absorbedBytes / 8)] ^=
BigInt(bytes[i]) << (BigInt(this.absorbedBytes % 8) * 8n);
this.absorbedBytes++;
if (this.absorbedBytes === this.rate) {
keccak(this.state);
this.absorbedBytes = 0;
}
}
}
squeeze() {
this.state[Math.floor(this.absorbedBytes / 8)] ^=
0x06n << (BigInt(this.absorbedBytes % 8) * 8n);
this.state[Math.floor((this.rate - 1) / 8)] ^= 0x8000000000000000n;
keccak(this.state);
if (this.outputSize <= this.rate) {
return new Uint8Array(this.state.buffer).slice(0, this.outputSize);
}
const keccakCount = Math.ceil(this.outputSize / this.rate);
const z = new Uint8Array(keccakCount * this.rate);
z.set(new Uint8Array(this.state.buffer).slice(0, this.rate));
for (let i = 1; i < keccakCount; i++) {
keccak(this.state);
z.set(new Uint8Array(this.state.buffer).slice(0, this.rate), i * this.rate);
}
return z.slice(0, this.outputSize);
}
}
export class SHA3XOF {
rate;
outputSize;
state = new BigUint64Array(25);
absorbedBytes = 0;
constructor(rate, outputSize) {
this.rate = rate;
this.outputSize = outputSize;
}
absorb(bytes) {
for (let i = 0; i < bytes.byteLength; i++) {
this.state[Math.floor(this.absorbedBytes / 8)] ^=
BigInt(bytes[i]) << (BigInt(this.absorbedBytes % 8) * 8n);
this.absorbedBytes++;
if (this.absorbedBytes === this.rate) {
keccak(this.state);
this.absorbedBytes = 0;
}
}
}
squeeze() {
this.state[Math.floor(this.absorbedBytes / 8)] ^=
0x1fn << (BigInt(this.absorbedBytes % 8) * 8n);
this.state[Math.floor((this.rate - 1) / 8)] ^= 0x8000000000000000n;
keccak(this.state);
if (this.outputSize <= this.rate) {
return new Uint8Array(this.state.buffer).slice(0, this.outputSize);
}
const keccakCount = Math.ceil(this.outputSize / this.rate);
const z = new Uint8Array(keccakCount * this.rate);
z.set(new Uint8Array(this.state.buffer).slice(0, this.rate));
for (let i = 1; i < keccakCount; i++) {
keccak(this.state);
z.set(new Uint8Array(this.state.buffer).slice(0, this.rate), i * this.rate);
}
return z.slice(0, this.outputSize);
}
}
function keccak(a) {
for (let i = 0; i < 24; i++) {
theta(a);
rho(a);
pi(a);
chi(a);
iota(a, i);
}
}
function theta(a) {
const c = new BigUint64Array(5);
for (let x = 0; x < 5; x++) {
c[x] = a[x];
c[x] ^= a[x + 5];
c[x] ^= a[x + 10];
c[x] ^= a[x + 15];
c[x] ^= a[x + 20];
}
const d = new BigUint64Array(5);
for (let x = 0; x < 5; x++) {
d[x] = c[(x + 4) % 5] ^ rotl64(c[(x + 1) % 5], 1);
}
for (let x = 0; x < 5; x++) {
for (let y = 0; y < 5; y++) {
a[x + y * 5] ^= d[x];
}
}
}
function rho(a) {
// Lane (0, 0) stays the same
const shifts = [
0, 1, 62, 28, 27, 36, 44, 6, 55, 20, 3, 10, 43, 25, 39, 41, 45, 15, 21, 8, 18, 2, 61, 56, 14
];
for (let i = 0; i < 25; i++) {
a[i] = rotl64(a[i], shifts[i]);
}
}
function pi(a) {
const dests = [
0, 10, 20, 5, 15, 16, 1, 11, 21, 6, 7, 17, 2, 12, 22, 23, 8, 18, 3, 13, 14, 24, 9, 19, 4
];
const temp = new BigUint64Array(a);
for (let i = 0; i < 25; i++) {
a[dests[i]] = temp[i];
}
}
function chi(a) {
const temp = new BigUint64Array(a);
for (let x = 0; x < 5; x++) {
for (let y = 0; y < 5; y++) {
a[x + 5 * y] ^= ~temp[((x + 1) % 5) + 5 * y] & temp[((x + 2) % 5) + 5 * y];
}
}
}
function iota(a, i) {
a[0] ^= iotaConstants[i];
}
const iotaConstants = new BigUint64Array([
0x0000000000000001n,
0x0000000000008082n,
0x800000000000808an,
0x8000000080008000n,
0x000000000000808bn,
0x0000000080000001n,
0x8000000080008081n,
0x8000000000008009n,
0x000000000000008an,
0x0000000000000088n,
0x0000000080008009n,
0x000000008000000an,
0x000000008000808bn,
0x800000000000008bn,
0x8000000000008089n,
0x8000000000008003n,
0x8000000000008002n,
0x8000000000000080n,
0x000000000000800an,
0x800000008000000an,
0x8000000080008081n,
0x8000000000008080n,
0x0000000080000001n,
0x8000000080008008n
]);

Xet Storage Details

Size:
4.96 kB
·
Xet hash:
cf37ab758c48e29b197783e42f252edcc2939d49103a8e6aae141adac6e03aa4

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.