“Finite Field Arithmetic.” Chapter 18B: "Cutouts" in Peh.

This article is part of a series of hands-on tutorials introducing FFA, or the Finite Field Arithmetic library. FFA differs from the typical "Open Sores" abomination, in that -- rather than trusting the author blindly with their lives -- prospective users are expected to read and fully understand every single line. In exactly the same manner that you would understand and pack your own parachute. The reader will assemble and test a working FFA with his own hands, and at the same time grasp the purpose of each moving part therein.


Chapter 18 consists of three parts, of which only the first (18A) includes a vpatch; the
second (18B) -- completes the discussion of the mechanisms; while the third (18C) contains worked examples of practical use.


You are presently reading 18B.

You will need:

  • A Keccak-based VTron (for this and all subsequent chapters.)
  • All of the materials from Chapters 1 - 18A.

There is no vpatch in Chapter 18B. To run the examples given in this Chapter, please use the Peh you built in Chapter 18A, and refer to the Peh 251K Instruction Set Table as you read on.


The time has come to discuss the intended applications of Peh.


Peh is constructed as a sane -- maximally-programmable, maximally built-for-smart-people, and maximally rodenticidal -- replacement for such broken-at-birth abominations as GPG, SSL, etc.

Unlike all currently-popular braindamaged cryptoware (e.g. Koch's GPG), Peh deliberately refrains from imposing any particular cryptographic algorithm on the operator.

Specifically, you are free to use any form -- or combination of forms -- of public or secret-key cryptography which can be expressed using Peh opcodes, interpreted in whatever agreed-upon sequence, to transform particular inputs into the necessary outputs. (At the most extreme minimum: only you and your counterparty need to agree! Let the enemy manually sweat over every stolen transmission, to determine what your algorithm and data representation happen to be -- why give him anything for free? Let him work to the bone.)


A well-crafted Peh Tape is a human-readable (to the trained eye) document, rather than "machine barf".

The particular method for the generation and demarcation of keys (public, private, secret), ciphertexts, plaintexts, signatures, etc. is deliberately left open to the operator. Working examples of Peh cryptosystems will, however, be offered in forthcoming chapters.

In typical usage, a Peh Tape (which, recall, may produce new Peh Tapes when executed) will represent one or more of the following mathematical objects:

  1. A Generator, which from some quantity of TRNG bits produces a new Private Key.
  2. A Private Key produced by a Generator (I).
  3. A Transformer, which, from a given Private Key (II), derives a distributable Public Key.
  4. A distributable Public Key produced by a Transformer (III).
  5. A distributable Encryptor, which produces a Ciphertext from an arbitrary Plaintext input (and some quantity of TRNG bits) that, in turn, can only be deciphered by a Decryptor (VII) derived from the associated Private Key (II). An Encryptor may be identical to a Public Key (IV), or be derived from same using a mechanical process.
  6. A distributable Ciphertext produced by an Encryptor (V).
  7. A Decryptor, derived from a Private Key (II), which, when given a Ciphertext (VI) that had been produced by a corresponding Encryptor (V), emits the corresponding Plaintext.
  8. A Signet Mold, which produces a Signet from a given Private Key (II).
  9. A Signet produced by a Signet Mold (VIII).
  10. A distributable Seal produced by invoking a Signet (IX) on a particular arbitrary Payload, making use of some quantity of TRNG bits.
  11. A distributable Litmus, derived from a given Public Key (IV); takes a Seal (X), and a given Payload, and determines whether said Seal was legitimately produced by invoking a Signet born from that Public Key's originating Private Key on that particular Payload.

However, given the freedom offered by Peh to the operator, some patterns of usage may involve moving parts different from those described above. In particular, the operator may choose to use entirely different private (and corresponding public) keys for signing and encryption; or some combination of "genuine" and "decoy" components; or, in certain exotic scenarios, sets of multiple private keys; or even some yet-unforeseen system that does not fit into the suggested outline at all!

The operator must remember that he alone is responsible for formulating correct cryptosystems for use with Peh, and/or enlisting trusted friends to help in doing so. The primitive opcodes offered in Peh provide for a foundation of fits-in-head and sidechannel-free arithmetic, but it is certainly possible to kill yourself and your counterparty by inept cryptosystem design ! You have been warned, and this warning -- which states a fact that ought to be obvious to the intelligent reader -- will not be repeated again. A sapper errs once!

We will return to discussing the cryptographic usage of Peh in subsequent Chapters.


Now, let's wrap up our discussion of the mechanisms offered in Chapter 18A.

The reader was introduced to the subroutine syntax of Peh, where a definition of the form:

@ Name @ Body ;

... permits the later invocation of the defined subroutine, in the form of:

@ Name !

... or, where a shorthand notation is desired:

!

... which invokes the most recently-defined (i.e. nearest to the left of the ! symbol) subroutine on the Tape.

Now we will discuss the restrictions imposed by Peh on the definition and invocation of subroutines, and the rationale for these restrictions.

Let's review again the last example set of erroneous Peh Tapes from 18A:

# Peh Tape Eggogology
1
@foo@[foo]@bar!; @bar@[bar]; @foo!

Cannot invoke Subroutine 'bar' before the position where it is defined!
2
@foo@[foo]!; @foo!

No Subroutines were defined prior to this position!
3
@foo@[foo]@foo!; @foo!

Recursive invocation in Subroutine 'foo' is prohibited!
4
@foo@@bar@[bar]; !

Attempted to define Subroutine 'bar' while inside a Loop or Subroutine!
5
: @foo@[foo];

Attempted to define Subroutine 'foo' while inside a Loop or Subroutine!

In Tape 1, the subroutine bar is invoked inside foo; but its definition resides to the right of the invocation point, which is prohibited:

ffa_calc.adb:

      -- Attempt to invoke a Subroutine with the supplied name:
      procedure Invoke_Named_Subroutine(Name : in Sub_Names) is
         -- Position of the current Proposed Sub in Sub Table:
         Index  : Subroutine_Table_Range := Lookup_Subroutine(Name);
         -- To invoke a Sub, it MUST exist in the Sub Table.
 
         -- Name of the Proposed Sub (for eggogs) :
         S_Name : String := String(Tape(Name.L .. Name.R));
      begin
         -- If no defined Subroutine has this Name, eggog:
         if Index = Subs'First then
            E("Invoked Undefined Subroutine '" & S_Name & "' !");
         end if;
         -- Otherwise, proceed to the invocation:
         declare
            -- The Sub Table Entry we successfully looked up:
            Sub : Sub_Def := Subs(Index);
         begin
            -- Recursion is prohibited in Peh Tapes. Detect it:
            if IP in Sub.Payload.L .. Sub.Payload.R then
               E("Recursive invocation in Subroutine '" 
                   & S_Name & "' is prohibited!");
            end if;
            -- Prohibit Subroutines whose definitions end AFTER the current IP:
            if IP < Sub.Payload.R then
               E("Cannot invoke Subroutine '" & S_Name &
                   "' before the position where it is defined!");
            end if;
            -- Proceed to invoke the Subroutine:
            Invoke_Subroutine(Sub);
         end;
      end Invoke_Named_Subroutine;

Observe that the recursive invocation in Tape 3 is likewise prohibited.

Re-definition of a subroutine, or the placement of a subroutine definition inside of a loop or subroutine (as seen in e.g. as in Tapes 4 and 5) is also prohibited:

ffa_calc.adb:

      -- Attempt to intern the given Subroutine into the Subroutines Table:
      procedure Intern_Subroutine(Sub : in Sub_Def) is
         -- Position of the current Proposed Sub in Sub Table:
         Index  : Subroutine_Table_Range := Lookup_Subroutine(Sub.Name);
         -- To DEFINE a Sub, it must NOT have existed in Sub Table.
 
         -- Name of the Proposed Sub (for eggogs) :
         S_Name : String := String(Tape(Sub.Name.L .. Sub.Name.R));
      begin
         -- If a Sub with this Name already exists, eggog:
         if Index /= Subs'First then
            E("Attempted to redefine Subroutine '" & S_Name & "' !");
         end if;
         -- Definitions are prohibited inside Loops or Sub calls:
         if Control_Stack_Not_Empty then
            E("Attempted to define Subroutine '" 
                & S_Name & "' while inside a Loop or Subroutine!");
         end if;
         -- If the Subroutine Table is full, eggog:
         if STP = Subs'Last then
            E("Cannot define the Subroutine '" & S_Name
                & ": the Subroutine Table is Full!");
         end if;
         -- Finally, intern the Proposed Subroutine into the Sub Table:
         STP       := STP + 1;
         Subs(STP) := Sub;
      end Intern_Subroutine;

There are two fundamental reasons for these restrictions.

The first of these is that every Peh Tape is a text meant to be maximally understandable to the human reader, i.e. a fits-in-head artifact. The intended reader, is, naturally, one who is in possession of whatever components (public and private) which may be required to carry out the computation represented by the given Tape. Point being, convoluted control flow is undesirable in Peh Tapes. Strong ciphers may rely on number-theoretical conjectures which offer "trapdoor transformation"; but never on "obfuscated program contests".

The second reason is that uniform left-to-right control flow (where the machine may "visit" an earlier location by invoking a subroutine, but may not transfer control to an earlier Tape position permanently a la "GOTO") permits the implementation of a Cutout mechanism, which allows safe sequential processing of multiple Peh Tapes -- in order to compute functions having both "public" and "private" inputs. This mechanism is the main subject of this Chapter.


Now we will discuss what a Cutout is, and how it is used.

There are only two Cutout control commands. Let's reproduce them here from the Peh 251K Instruction Set given in the previous Chapter:

Peh Instruction Set Ver. 251K
Op Description # Ins # Outs Notes
LC Mark Left Side of Cutout 0 0 Mark the start of the optional Cutout Tape segment. When the Cutout is armed by the closing RC instruction, Subroutines defined after the LC Position, but prior to the RC, may be invoked from Positions after the RC. Subroutines defined prior to the LC Position may be invoked from Positions prior to the RC, but not from those after RC. Fatal if a RC to mark the end of the Cutout does not occur at some later point. Fatal if executed more than once in a Peh run.
RC Mark Right Side of Cutout, and Arm 0 0 Mark the end of the Cutout, and arm it. Once armed, the Cutout remains in force until Peh halts, and may not be disabled or redefined. All subsequent instructions must obey the Cutout (see LC) or will trigger fatal error. Register-access instructions, including ZR and QD, executed prior to this Position will access only the segregated Cutout Register Set. Fatal if a LC has not executed prior. Fatal if executed more than once in a Peh run.

A Cutout is an optional feature of Peh which may be activated only once in a given Peh run. When proclaimed using a matching pair of LC and RC opcodes, it divides the Peh Tapespace into the following three logical segments:

Guarded L C Cutout R C Public

The Guarded segment is understood to span from the first position in the Tapespace to the one immediately before the LC opcode; the Cutout segment spans from the LC position to that of the RC; and the Public segment spans from the position immediately after the RC, to the very last position in the Tapespace.

If LC executes inside a particular Peh run, denoting the start of the Cutout, a RC must also execute to denote its end: or the run will produce an Eggog verdict regardless of what else happens.

A Cutout is intended for use in a Peh session where the Tapespace is filled with two or more Tapes intended to be executed sequentially. It denotes a constrained subset of subroutines on the first Tape which may be invoked from the subsequent Tapes. Subroutines which do not fall into this denoted subset, may not be directly invoked from the later Tapes.

After RC executes, the Cutout is armed in the particular Peh run; it may not be disarmed or redefined, and the following restrictions will remain in place until Peh halts:

  1. The Cutout is unaffected by the Zap commands.
  2. Any further execution of an LC or RC command triggers an immediate halt with a verdict of Eggog..
  3. The Cutout may not bisect a Subroutine definition or a Loop structure. Attempting to do this results in halting with a verdict of Eggog.
  4. A Subroutine defined inside the Guarded segment may be invoked from inside the Guarded segment. (The restriction discussed earlier, where Subroutines may only be invoked when they have been defined to the left of the invocation point -- remains in force, here and elsewhere below.)
  5. A Subroutine defined in either the Guarded or the Cutout segments may be called from inside the Cutout segment.
  6. A Subroutine defined inside the Cutout segment may be called from inside the Public segment.
  7. A Subroutine defined inside the Guarded segment may not be called from inside the Public segment. Any attempt to do so results in halting with a verdict of Eggog.
  8. All Register-accessing opcodes (including Zaps and Debug Print) which execute inside either the Guarded or the Cutout segments, will make use exclusively of the segregated Cutout Register Set.
  9. All Register-accessing opcodes (including Zaps and Debug Print) which execute inside the Public segment, will make use exclusively of the Ordinary Register Set.

It should be apparent to the alert reader that only the Data Stack may be used to move information between the Public segment and the other two, while Registers cannot be so used. (Peh Tapes which do not arm the Cutout may pass data to/from subroutines using Registers; as may Peh Tapes which do make use of it, but strictly within either of the two sides of the Tapespace that are separated by RC.)


The alert reader will also have guessed that the term "Cutout" is lifted from that of the traditional spycraft concept, where it refers to a trusted courier who carries information between two parties that are unable to speak directly to one another.


Now, let's review some examples of valid Tapes demonstrating the use of a Cutout:

Peh Tape Output of Tape

@aa@[a]; LC @bb@[b]@aa!; RC @bb! QY

ba

@aa@[bar]; LC @bb@[foo]@aa!; RC @bb! QY

foobar

@aa@[bar]; LC @bb@[foo]@aa!; RC @baz@[baz]; @baz! QY

baz

@yy@[yy]; @xx@[xx]@yy!; LC @foo@[foo]@xx!; RC @foo! QY

fooxxyy

And now, some invalid (i.e. leading mercilessly to an Eggog Verdict) examples:

Peh Tape Eggogology

@aa@[a]; LC @bb@[b]@aa!; RC @aa! QY

FATAL: Tick: 32, IP: 32, Symbol: '!' : Attempted movement to IP: 5 violates the Cutout!

@yy@[yy]; @xx@[xx]@yy!; LC @foo@[foo]@xx!; RC @yy! QY

FATAL: Tick: 50, IP: 50, Symbol: '!' : Attempted movement to IP: 5 violates the Cutout!

@yy@[yy]; @xx@[xx]@yy!; LC RC ! QY

FATAL: Tick: 31, IP: 31, Symbol: '!' : Attempted movement to IP: 15 violates the Cutout

Why would you want to use a Cutout in practice? Let's say you have a subroutine which puts a "private" constant on the Data Stack, e.g.:

@PrivConst@.DEADF00D;

... that you can later invoke as:

@PrivConst!

This is the standard method for the use of constants in Peh Tapes.

Now, suppose that you have decided to use a cryptosystem where the private component is fed into Peh immediately prior to a Ciphertext Tape provided by a third party. In order to emit its Plaintext payload, the Ciphertext Tape is permitted to invoke a specific set of private operations defined in the first Tape; but it should not be able to invoke any other subroutines which may have been defined there.

In particular, you do not want the third-party Ciphertext to be able to cause a copy of an arbitrary private constant to be emitted into the output of the Peh run (which could undesirably litter an "uncleanable" solid-state disk with long-term secrets; or cause them to be displayed on a monitor subject to peeking; or attempt to transmit them by radio using a crafted CPU-grind loop; etc.) Consequently, you will want a Cutout of the following form:

Tapespace
(Contains two concatenated Tapes)
Left Tape, Executed First Right Tape
@PrivP@.DEADF00D; LC @DoPrivOp@@PrivP! R* ; RC .3 @DoPrivOp!
Guarded Cutout Public

Hence, the subroutine DoPrivOp may be invoked in the Public segment (i.e. the entire remainder of the Tapespace to the right of RC), but PrivP may not, even if the author of the second Tape knew its name. And any Register operations which happen on the left side of the RC, will use a segregated register set, which cannot be accessed from the portion of the Tapespace which resides to the right of the RC. This segregated register set may hold temporary values that are used by the "private" operations, for instance.

If you append a QD command to the end of the above Tape, and feed it to a Peh invoked with adequate Tapespace and a 256-bit FZ width, you will get the following debug output:

Data Stack:
    1 : 000000000000000000000000000000000000000000000000000000029C09D027
Control Stack:
Registers:
    g : 0000000000000000000000000000000000000000000000000000000000000000
    h : 0000000000000000000000000000000000000000000000000000000000000000
    i : 0000000000000000000000000000000000000000000000000000000000000000
    j : 0000000000000000000000000000000000000000000000000000000000000000
    k : 0000000000000000000000000000000000000000000000000000000000000000
    l : 0000000000000000000000000000000000000000000000000000000000000000
    m : 0000000000000000000000000000000000000000000000000000000000000000
    n : 0000000000000000000000000000000000000000000000000000000000000000
    o : 0000000000000000000000000000000000000000000000000000000000000000
    p : 0000000000000000000000000000000000000000000000000000000000000000
    q : 0000000000000000000000000000000000000000000000000000000000000000
    r : 0000000000000000000000000000000000000000000000000000000000000000
    s : 0000000000000000000000000000000000000000000000000000000000000000
    t : 0000000000000000000000000000000000000000000000000000000000000000
    u : 0000000000000000000000000000000000000000000000000000000000000000
    v : 0000000000000000000000000000000000000000000000000000000000000000
    w : 0000000000000000000000000000000000000000000000000000000000000000
    x : 0000000000000000000000000000000000000000000000000000000000000000
    y : 0000000000000000000000000000000000000000000000000000000000000000
    z : 0000000000000000000000000000000000000000000000000000000000000000
Subroutines:
    1 : 'PrivP' ( 8, 17 ) (Guarded)
    2 : 'DoPrivOp' ( 32, 43 ) (Cutout)
Cutout: Armed: ( 20, 46 )
Flag  : 0
Ticks : 85
IP    : 63
WARNING: Tape terminated with a non-empty Data Stack!
WARNING: Tape terminated without a Verdict.

Admittedly this is a simplistic example, but it will have to suffice for now.


Now let's look at the implementation mechanism, which is uncomplicated. First, the data structures which represent the Cutout and the two Register Sets:

ffa_calc.adb:

   -- Start a Peh Machine with the given Dimensions and Tape; return a Verdict.
   function Peh_Machine(Dimensions : in Peh_Dimensions;
                        Tape       : in Peh_Tapes;
                        RNG        : in RNG_Device) return Peh_Verdicts is
 
   ............
 
      subtype Cutouts    is Segment; -- Cutout (see Ch.18 discussion)
 
   ............
 
      -- Registers:
      subtype RegNames is Character range 'g' .. 'z';
      type RegTables is array(RegNames range <>) of FZ(1 .. Wordness);
 
      -- Ordinary Register Set (accessed if no Cutout, or when ABOVE it)
      Registers     : RegTables(RegNames'Range);
 
      -- 'Cutout' Register Set (accessed only if IP is IN or BELOW the Cutout)
      CO_Registers  : RegTables(RegNames'Range);
 
   ............
 
      -- 'Cutout' Tape Segment. (See Ch.18 discussion re: when and how to use.)
      -- If the Cutout is armed, it stays armed until Peh halts.
      Cutout_Begun  : Boolean      := False;
      Cutout_Armed  : Boolean      := False;
      Cutout        : Cutouts;
 
   ............


The opcodes which declare and arm the Cutout:

ffa_calc.adb:

 
   ............
 
            ---------------------------------------------------------
            -- Left...
            when 'L' =>
 
               -- Which L-op?
               case O is
 
                  ............
                  ............
 
                  -- ... 'Cutout' :
                  -- Mark the LEFT SIDE of the 'Cutout' Tape segment;
                  -- The Tape IN OR PRIOR to it will retain the ability to
                  -- move directly into points PRIOR to THIS position
                  -- on the Tape (i.e. where THIS Op had executed).
                  -- Ops on Tape AFTER 'RC' mark can move INTO Cutout,
                  -- but NOT directly into any position PRIOR to it.
                  -- If 'LC' is executed, a 'RC' MUST occur before Tape end.
                  -- FATAL if a 'LC' or 'RC' Op had previously executed.
                  when 'C' =>
                     -- Eggog if we have ALREADY begun the Cutout somewhere:
                     if Cutout_Begun then
                        E("'LC' Op may only execute ONCE on a Tape!");
                     end if;
                     -- Cutout defs are prohibited inside loops or Sub calls:
                     if Control_Stack_Not_Empty then
                        E("Attempted to execute 'LC' (Left-Cutout)" &
                            " inside a Loop or Subroutine!");
                     end if;
                     -- Set the START of the Cutout, and mark it 'begun':
                     Cutout_Begun := True;
                     Cutout.L     := IP;
 
                  -- ... Unknown (Eggog):
                  when others =>
                     Undefined_Prefix_Op;
 
               end case;
            ---------------------------------------------------------
            -- Right...
            when 'R' =>
 
               -- Which R-op?
               case O is
 
                  ............
                  ............
 
                  -- ... 'Cutout' :
                  -- Mark the RIGHT SIDE of the 'Cutout' Tape segment that
                  -- began with 'LC', and permanently arms the Cutout.
                  -- After THIS position, no IP_Next may be set which
                  -- directly transfers control to a point PRIOR to 'LC'.
                  -- FATAL if no 'LC' had executed to mark the LEFT SIDE.
                  when 'C' =>
                     -- Eggog if we never marked the beginning with 'LC':
                     if not Cutout_Begun then
                        E("'RC' Op found, but no there was no prior 'LC' !");
                     end if;
                     -- Eggog if we have already armed the Cutout:
                     if Cutout_Armed then
                        E("'RC' Op found, but the Cutout is already armed!");
                     end if;
                     -- Cutout defs are prohibited inside loops or Sub calls:
                     if Control_Stack_Not_Empty then
                        E("Attempted to execute 'RC' (Right-Cutout)" &
                            " inside a Loop or Subroutine!");
                     end if;
                     -- Otherwise proceed to complete and arm the Cutout:
                     Cutout.R     := IP;
                     Cutout_Armed := True;
 
                  -- ... Unknown (Eggog):
                  when others =>
                     Undefined_Prefix_Op;
 
               end case;


The predicates which answer questions concerning a given Tape Position's relation vis-a-vis the Cutout:

ffa_calc.adb:

 
   ............
 
      ------------
      -- Cutout --
      ------------
 
      -- Find whether Cutout would prohibit move from current IP to the given :
      function Cutout_Prohibits(Position : in Tape_Positions) return Boolean is
      begin
         return Cutout_Armed and IP > Cutout.R and Position < Cutout.L;
      end Cutout_Prohibits;
 
 
      -- Find whether given a Tape Position lies inside an armed Cutout:
      function In_Cutout(Position : in Tape_Positions) return Boolean is
      begin
         return Cutout_Armed and Position in Cutout.L .. Cutout.R;
      end In_Cutout;
 
 
      -- Determine whether to use the Cutout Registers at the current position:
      function Use_CO_Registers return Boolean is
      begin
         -- If we are either BELOW or INSIDE armed Cutout : we use only the
         -- CO_Registers alternative register file. Otherwise: use Registers.
         return Cutout_Armed and IP <= Cutout.R;
      end Use_CO_Registers;
 
   ............


The behaviour of the Zap operations, as they concern the Cutout:

ffa_calc.adb:

 
   ............
 
      ----------
      -- Zaps --
      ----------
 
      -- Zero the Data Stack and reset the SP:
      procedure Zap_Data_Stack is
      begin
         -- Clear the Data Stack:
         for i in Stack'Range loop
            FFA_FZ_Clear(Stack(i));
         end loop;
         -- Set SP to bottom:
         SP := Stack_Positions'First;
      end Zap_Data_Stack;
 
 
      -- Zero all Registers (Ordinary set) :
      procedure Zap_Ordinary_Registers is
      begin
         for r in RegNames'Range loop
            FFA_FZ_Clear(Registers(r));
         end loop;
      end Zap_Ordinary_Registers;
 
 
      -- Zero all Registers (Cutout set) :
      procedure Zap_Cutout_Registers is
      begin
         for r in RegNames'Range loop
            FFA_FZ_Clear(CO_Registers(r));
         end loop;
      end Zap_Cutout_Registers;
 
 
      -- Zero all Registers in the currently-active Register Set:
      procedure Zap_Registers is
      begin
         if Use_CO_Registers then
            Zap_Cutout_Registers;
         else
            Zap_Ordinary_Registers;
         end if;
      end Zap_Registers;
 
   ............


The behaviour of the Register access operations, as they concern the Cutout:

ffa_calc.adb:

 
   ............
 
               -------------------------
               -- Fetch from Register --
               -------------------------
            when 'g' .. 'z' =>
               -- Put value of Register on stack
               Push;
               if Use_CO_Registers then
                  Stack(SP) := CO_Registers(C); -- use Cutout Register set
               else
                  Stack(SP) := Registers(C);    -- use ordinary set
               end if;
 
   ............
   ............
 
            ---------------------------------------------------------
            -- Zap...
            when 'Z' =>
 
               -- .. Zap what?
               case O is
 
                  -- ... Registers:
                  when 'R' =>
                     -- If in Cutout, will zap only Cutout set of regs
                     Zap_Registers;
 
                  -- ... Data Stack:
                  when 'D' =>
                     Zap_Data_Stack;
 
                  -- ... Overflow Flag:
                  when 'F' =>
                     Zap_Flag;
 
                  -- ... All Zappable State:
                  when 'A' =>
                     Zap_Master;
 
                  when others =>
                     Undefined_Prefix_Op;
 
               end case;
 
            ---------------------------------------------------------
            -- Write into Register...
            when '$' =>
 
               -- Eggog if operator gave us a garbage Register name:
               if O not in RegNames then
                  E("There is no Register '" & O & "' !");
               end if;
 
               -- Selected Register exists; move top FZ on stack into it:
               Want(1);
               if Use_CO_Registers then
                  CO_Registers(O) := Stack(SP); -- use Cutout Register set
               else
                  Registers(O)    := Stack(SP); -- use ordinary set
               end if;
               Drop;


And, finally, the execution mechanism of Ch. 18A, where the Cutout is actually enforced:

ffa_calc.adb:

 
   ............
 
      -----------------------------
      -- Start of Tape Execution --
      -----------------------------
 
   begin
      -- Reset all resettable state:
      Zap_Master;
      Zap_Cutout_Registers;
 
      -- Execution begins with the first Op on the Tape:
      IP := Tape_Positions'First;
 
      loop
 
         -- If current Op is NOT the last Op on the Tape:
         if not Last_Tape_Symbol then
 
            -- ... then default successor of the current Op is the next one:
            IP_Next := IP + 1;
 
         else
 
            -- ... but if no 'next' Op exists, or quit-with-Mu, we stay put:
            IP_Next := IP; -- ... this will trigger an exit from the loop.
 
         end if;
 
         -- Advance Odometer for every Op (incl. prefixes, in comments, etc) :
         Ticks := Ticks + 1;
 
         -- Execute the Op at the current IP:
         Op(Tape(IP));
 
         -- Halt when...
         exit when
           Verdict /= Mu or -- Got a Verdict, or...
           IP_Next  = IP or -- Reached the end of the Tape, or...
           Exhausted_Life;  -- Exhausted Life.
 
         -- If the Cutout has been armed on this Tape, then enforce it:
         if Cutout_Prohibits(IP_Next) then
            E("Attempted movement to IP:" & Tape_Positions'Image(IP_Next) &
                " violates the Cutout!");
         end if;
 
         -- We did not halt yet, so select the IP of the next Op to fetch:
         IP := IP_Next;
 
      end loop;
 
      -- At this point, the Tape has halted.
 
      ............
 
      -- Unclosed Cutout:
      if Cutout_Begun and not Cutout_Armed then
         E("The Cutout declaration 'LC' at IP:"
             & Tape_Positions'Image(Cutout.L) & " is Unterminated!");
      end if;
 
      ............

It is really quite simple -- any transfer of control flow which violates an armed Cutout, immediately triggers a halt with Eggog verdict.



In the next Chapter, 18C, we will walk through a set of practical examples which make use of the currently-defined Peh opcodes.


~To be continued!~

This entry was written by Stanislav , posted on Monday April 15 2019 , filed under Ada, Bitcoin, Cold Air, Computation, Cryptography, FFA, Friends, Mathematics, SoftwareArchaeology, SoftwareSucks . Bookmark the permalink . Post a comment below or leave a trackback: Trackback URL.

2 Responses to ““Finite Field Arithmetic.” Chapter 18B: "Cutouts" in Peh.”

  • hapax says:

    Hey,

    Looks like the debug output was produced by the following tape instead of the example one.

    @PrivP@.DEADF00D; LC @DoPrivOp@@PrivP! R* ; RC .3 @DoPrivOp! QD

    Just the name, but still, made me reread that part.

    ---hapax

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre lang="" line="" escaped="" highlight="">


MANDATORY: Please prove that you are human:

45 xor 84 = ?

What is the serial baud rate of the FG device ?


Answer the riddle correctly before clicking "Submit", or comment will NOT appear! Not in moderation queue, NOWHERE!