How To Verify A Stakedy Post

     The purpose of verifying a post is to ensure the rules have been followed. In order to a verify a post, you need to decrypt certain values and then put those decrypted values into the open source algorithm. The result of the algorithm using the decrypted values should be as expected. It's important that verifiers make sure the algorithm contains the expected logic. In addition, the encrypted data is stored in multiple places and should be verified for consistency over time.
     In order to verify a post, the resolution date (the "Slash Date") must have occurred. If the Slash Date has not yet occurred, the post can not yet be verified. Once the Slash Date is reached, decryption keys are publicly revealed on each post. Decrypting the data reveals the Random Threshold, votes, and other parameters used inside of the open source accountability algorithm.
     Once decryption keys are publicly revealed, verifiers can decrypt the encrypted data included with each post. There are two basic types of encrypted data: 1) the initial post; and 2) votes. To decrypt the data to its final format, the following nodejs code is provided. The verifier need only to set the encrypted variable string and decryption keys before executing the code.

  // M.I.T. LICENSE - FREE OPEN SOURCE SOFTWARE
  // ENTER ENCRYPTED DATA AND DECRYPTION KEYS INTO INPUT VARIABLES BELOW, THEN EXECUTE THE CODE USING NODEJS
  // AFTER EXECUTION, DECRYPTED DATA IS DISPLAYED LOGGED AS OUTPUT

  'use strict';
  const crypto = require('crypto');
  let algorithm = "aes-192-cbc"; // encryption algorithm to use
  let ENCRYPTED_DATA = ""; // input data from verify panel on stakedy.com
  let DECRYPTION_KEY1 = ""; // decrypt key1 from verify panel on stakedy.com
  let DECRYPTION_KEY2 = ""; // decrypt key2 from verify panel on stakedy.com
  console.log("FINAL DATA",decryptStakedy()); // output of decryption
  // CREATE POST STRUCTURE: "m-" + tempMax + "|m1-" + tempMin1 + "|m2-" + tempMin2 + "|r1-" + tempReject1 + "|r2-" + tempReject2 + "|s-" + stakeTokens + "|p-" + postId + "|v-" + minVotes + "|d-" + slashDate + "|" + randomPad
  // VOTE STRUCTURE: "v-" + voteTokens + "|t-" + judgeType + "|p-" + postId + "|" randomPad;

  function decryptStakedy() {
    let key2 = Buffer.from(DECRYPTION_KEY1, "hex"); // convert back to Buffer
    let iv2 = Buffer.from(DECRYPTION_KEY2, "hex"); // convert back to Buffer
    let decipher2 = crypto.createDecipheriv(algorithm, key2, iv2);
    let decrypted2 = decipher2.update(ENCRYPTED_DATA, 'hex', 'utf8') + decipher2.final('utf8'); // deciphered text    
    // from decrypted2 - parse the keyHex1 and ivHex1
    let encryptedText1 = decrypted2.substring(0,decrypted2.length - 48 - 32);
    let keyHex1 = decrypted2.substring(decrypted2.length - 48, decrypted2.length);
    let ivHex1 = decrypted2.substring(decrypted2.length - 48 - 32, decrypted2.length - 48);
    let key1 = Buffer.from(keyHex1, "hex"); // convert back to Buffer
    let iv1 = Buffer.from(ivHex1, "hex"); // convert back to Buffer
    let decipher1 = crypto.createDecipheriv(algorithm, key1, iv1);
    let decrypted1 = decipher1.update(encryptedText1, 'hex', 'utf8') + decipher1.final('utf8'); // deciphered text
    return decrypted1;
  }
     Once the encrypted data has been decrypted, the final values can then be input into the open-source algorithm below to verify the slashing result.

  // M.I.T. LICENSE - FREE OPEN SOURCE SOFTWARE
  // ENTER DECRYPTED DATA INTO INPUT VARIABLES BELOW, THEN EXECUTE THE CODE
  // AFTER EXECUTION, VERIFICATION RESULT IS DISPLAYED LOGGED AS OUTPUT

  'use strict';
  let tempMax = 0; // input "m" from post decryption above
  let tempMin1 = 0; // input "m1" from post decryption above
  let tempMin2 = 0; // input "m2" from post decryption above
  let tempReject1 = 0; // input "r1" from post decryption above
  let tempReject2 = 0; // input "r2" from post decryption above
  let stakeTokens = 0; // input "s" from post decryption above
  let minVotes = 0; // input "v" from post decryption above
  let acceptTokens = 0; // input "v" from vote decryption above - sum of all votes with "t" of yes (judgeType of yes)
  let rejectTokens = 0; // input "v" from vote decryption above - sum of all votes with "t" of no (judgeType of no)
  let voteCount = 0; // the count of all vote submissions (both accept and reject)
  let maxWithdrawRate = 0; // max withdraw rate from verify panel on stakedy.com (celody decentralized voting law at time of slash date)
  console.log("FINAL RESULT",verifyStakedy()); // output of verification (tokens paid,slashed or not slashed)

  function verifyStakedy() {
    let maxTokens = Math.min(tempMax, 2 * Number(stakeTokens));
    let minTokens = Math.min(tempMin1, tempMin2 * Number(stakeTokens));
    let rejectThresh = Math.min(tempReject1, tempReject2 * Number(stakeTokens));
    let isAboveMin = "no";
    // check if the vote tokens sum is above the min
    if (Number(acceptTokens) + Number(rejectTokens) > Number(minTokens)) {
        isAboveMin = "yes";
    }
    // calculate the reject scale factor
    let rejectScaleFactor = 0;
    if ((!rejectTokens) || (Number(rejectTokens) === 0) || (!rejectThresh) || (Number(rejectThresh) === 0)) {
        rejectScaleFactor = 0;
    } else {
        if (Number(rejectTokens) < Number(rejectThresh)) {
            rejectScaleFactor = Number(rejectTokens) / Number(rejectThresh);
        } else {
            rejectScaleFactor = Number(rejectThresh) / Number(rejectTokens);
        }
    }
    // determine if slashed
    let checkResult = "no";
    if ((isAboveMin === "yes") && (Number(rejectTokens) > Number(rejectThresh))) {
        checkResult = "yes";
    } else {
        checkResult = "no";
    }
    // check if above max payments
    let isAboveMax = "no";
    if (Number(acceptTokens) + Number(rejectTokens) > Number(maxTokens)) {
        isAboveMax = "yes";
    }
    // calculate the gross token payment - excludes stake, uses scale factor
    let grossPayments = 0;
    if (isAboveMax === "no") {
        grossPayments = (Number(acceptTokens) + Number(rejectTokens)) * rejectScaleFactor;
    } else {
        grossPayments = Number(maxTokens) * rejectScaleFactor;
    }
    // check if above the withdraw limit
    let isAboveWithdraw = "no";
    if (Number(grossPayments) > Number(maxWithdrawRate) * (Number(acceptTokens) + Number(rejectTokens))) {
        isAboveWithdraw = "yes";
    }
    // if above the withdraw limit, cap the gross payments
    if (isAboveWithdraw === "yes") {
        grossPayments = Number(maxWithdrawRate) * (Number(acceptTokens) + Number(rejectTokens));
    }
    // calculate how many tokens to return to wallet (includes stake)
    let finalResult = 0;
    if (checkResult === "no") {            
        finalResult = Number(grossPayments) + Number(stakeTokens);        
    } else {
        finalResult = Number(grossPayments);        
    }
    // circuit guard for low votes
    if (voteCount < minVotes) {        
        checkResult = "no";
        finalResult = Number(stakeTokens);
    }
    finalResult = "TOKENS TO STAKER: " + finalResult + " | SLASHED: " + checkResult;
    return finalResult;
  }