The Machines · Runtime stack

seedshaker

A reckoner seed: shaker's reversible obfuscation over lists of numbers — machines/seeds/seedshaker.shoddy

the seedshaker machine's icon

Summary

seedshaker bridges shaker’s four-round Feistel obfuscation onto the stack, the reckoner calculator’s working pile of values. Obfuscation is a reversible scramble, and a Feistel scheme is one that mixes the values in repeated passes — four here — each of which can be run backwards. The words are SHAKE, UNSHAKE, UNSHAKEOR, SHAKEOK and SHAKEMOD. shaker.shoddy already deals in nothing but lists of numbers. So no conversion happens at the bridge beyond the usual LIST-of-Cell reading every seed does.

Why It's Useful

Almost nothing crosses this bridge, and that is the point. shaker.shoddy already deals in lists of whole numbers, which is what the stack already holds. So the seed adds no conversion. It adds three guard questions, which shaker asks with an Error and this seed asks with a refusal: is the key empty, is every message value a whole number inside the field, and does the checksum still match the body.

The field is the range of numbers the scramble works over: 0 .. SHAKEMOD - 1. SHAKEMOD is registered as a word, rather than left as a number to remember, because every guard here is stated in terms of it. A value outside the field, or one that is not whole, has no obfuscation defined for it at all.

User's Guide

The round trip is the whole of it. SHAKE appends one extra value, a checksum — a check number computed from the message — so the cipher (the scrambled output) is always one longer than the message:

> SHAKEMOD
x: 67108859
> CLEAR { 11 22 33 } { 42 7 } SHAKE
x: { 23565951 8709952 16780855 52976830 }
> CLEAR { 11 22 33 } { 42 7 } SHAKE { 42 7 } UNSHAKE
x: { 11 22 33 }
> CLEAR { 11 22 33 } { 42 7 } SHAKE SHAKEOK
x: True

What the checksum does and does not catch. SHAKEOK asks whether the checksum still matches the body. That is a question about the message, not about the key, so it gives the same answer whoever asks it. A tampered cipher is caught:

> CLEAR { 1 2 3 } SHAKEOK
x: False

but a wrong key is not. Run UNSHAKE under a key that never encrypted this message and it answers values rather than refusing. They are simply the wrong values:

> CLEAR { 11 22 33 } { 42 7 } SHAKE { 99 } UNSHAKE
x: { 17450296 17399842 66970097 }

Know that before relying on it. UNSHAKEOR’s default is reached when the key is empty, when a value is out of field, or when the checksum fails. It is not reached when the key is merely the wrong one, because nothing in the cipher records which key made it.

The refusals are the guards shaker would otherwise have aborted on:

> CLEAR { 11 22 33 } { 42 7 } SHAKE { } UNSHAKE
?: UNSHAKE: THE KEY IS EMPTY
> CLEAR { 1.5 } { 42 } SHAKE
?: SHAKE: EVERY MESSAGE VALUE MUST BE A WHOLE NUMBER IN 0 .. 67108858

Word Reference

WordDescription
SHAKE ( list keys -- cipher )The list, obfuscated under keys — one value longer, the last a tamper checksum.
UNSHAKE ( cipher keys -- list )The message SHAKE produced, or a refusal if the key is empty or the checksum does not match.
UNSHAKEOR ( cipher keys dflt -- list )UNSHAKE, or dflt unchanged when the key is empty, out of field, or the checksum does not match.
SHAKEOK ( list -- flag )Whether the checksum SHAKE appended still matches the body.
SHAKEMOD ( -- n )The field size: every SHAKE value is a whole number in 0 .. n-1.

Who Uses It

UserHow
halifaxThe calculator's obfuscation words: SHAKE, UNSHAKE, UNSHAKEOR, SHAKEOK and SHAKEMOD.
sparkySparky folds it too, so a model calling eval reaches the same words halifax puts at a prompt.

A mill — a complete Shoddy program — claims this seed by folding RckSeedShaker over its reckoner state. That is all halifax does.

The Machines It Uses

MachineWhy
cuttleThe Cell type every bridged word reads its arguments from and answers into.
reckonerRckReg, RckSeeding and the argument readers every registered word is built from.
seqList plumbing under the LIST-of-NUMBER reader.
shakerThe domain this seed bridges: ShakeEncrypt, ShakeDecrypt, ShakeDecryptOr, ShakeVerify and ShakeModulus.