dosyspongeaont
Version:
reversible all-or-nothing package transform using dosysponge
73 lines (65 loc) • 2.05 kB
JavaScript
;
{
const sponge = require('dosysponge');
const BLOCK_SIZE_OCTETS = 512;
const RATE = BLOCK_SIZE_OCTETS;
const CAPACITY = 22; // total state size of sponge is rate * capacity
const SHIFT = 3;
const dosyspongeaont = {
aont, pad, chunk
};
try { module.exports = dosyspongeaont; } catch(e) { Object.assign( self, { dosysponeagont } ); }
function aont( m, { inverse : inverse = false } = {}) {
console.log( inverse );
const s = sponge_instance();
const c = chunk( pad( m, {inverse} ) );
const first_cover = s.squeeze( 512, { out_format : 'bytes' , iterations: 8 });
const output = new Array();
let cover = first_cover;
for( const chunk of c ) {
const block = xor( chunk, cover );
if ( inverse ) {
s.absorb( block );
} else {
s.absorb( chunk );
}
cover = s.squeeze( 512, { out_format: 'bytes' } );
output.push( block );
}
let result = output.join('');
if ( inverse ) {
result = result.slice(BLOCK_SIZE_OCTETS,-BLOCK_SIZE_OCTETS);
}
return result;
}
function xor( mc = '', bytes = new Uint8Array ) {
// FIXME: does not work with Unicode
const mb = mc.split('').map( c => c.codePointAt(0) );
mb.forEach( (v,i) => {
mb[i] ^= bytes[i];
});
return mb.map( v => String.fromCodePoint(v) ).join('');
}
function sponge_instance() {
const [rate, capacity, shift] = [RATE, CAPACITY, SHIFT];
return new sponge.DosySponge( { rate, capacity, shift } );
}
function pad( m, { inverse } ) {
const p = (BLOCK_SIZE_OCTETS - (m.length % BLOCK_SIZE_OCTETS)) % BLOCK_SIZE_OCTETS;
let padding = '';
if ( ! inverse ) {
padding = new Array(BLOCK_SIZE_OCTETS+1).join('0');
}
return padding + m + (new Array(p+1).join('0')) + padding;
}
function chunk( m ) {
return m.split('').reduce( (C,mc,i) => {
if ( i % BLOCK_SIZE_OCTETS ) {
C[C.length-1] += mc;
} else {
C.push(mc);
}
return C;
}, []);
}
}