All files / src/plugins redactedmap.ts

100% Statements 29/29
100% Branches 0/0
100% Functions 5/5
100% Lines 29/29

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133  27x 27x 27x 27x   27x 27x                                           26x 26x       26x 26x       26x 26x       26x 26x     26x                               20x 20x   20x                       41x 41x 41x 41x       27x                           22x         22x                       19x 19x 19x       19x                  
export {
  RedactedMinaNFTMapCalculation,
  RedactedMinaNFTMapState,
  RedactedMinaNFTMapStateProof,
  MapElement,
};
import { Field, SelfProof, ZkProgram, Struct, Poseidon } from "o1js";
import { Metadata, MetadataWitness } from "../contract/metadata";
 
class MapElement extends Struct({
  originalRoot: Metadata,
  redactedRoot: Metadata,
  key: Field,
  value: Metadata,
}) {}
 
class RedactedMinaNFTMapState extends Struct({
  originalRoot: Metadata, // root of the original Map
  redactedRoot: Metadata, // root of the Redacted Map
  hash: Field, // hash of all the keys and values of the Redacted Map
  count: Field, // number of keys in the Redacted Map
}) {
  static create(
    element: MapElement,
    originalWitness: MetadataWitness,
    redactedWitness: MetadataWitness
  ) {
    // TODO: remove comments from key validation after https://github.com/o1-labs/o1js/issues/1552
    const [originalDataWitnessRoot, originalDataWitnessKey] =
      originalWitness.data.computeRootAndKey(element.value.data);
    element.originalRoot.data.assertEquals(originalDataWitnessRoot);
    //originalDataWitnessKey.assertEquals(element.key);
 
    const [originalKindWitnessRoot, originalKindWitnessKey] =
      originalWitness.kind.computeRootAndKey(element.value.kind);
    element.originalRoot.kind.assertEquals(originalKindWitnessRoot);
    //originalKindWitnessKey.assertEquals(element.key);
 
    const [redactedDataWitnessRoot, redactedDataWitnessKey] =
      redactedWitness.data.computeRootAndKey(element.value.data);
    element.redactedRoot.data.assertEquals(redactedDataWitnessRoot);
    //redactedDataWitnessKey.assertEquals(element.key);
 
    const [redactedKindWitnessRoot, redactedKindWitnessKey] =
      redactedWitness.kind.computeRootAndKey(element.value.kind);
    element.redactedRoot.kind.assertEquals(redactedKindWitnessRoot);
    //redactedKindWitnessKey.assertEquals(element.key);
 
    return new RedactedMinaNFTMapState({
      originalRoot: element.originalRoot,
      redactedRoot: element.redactedRoot,
      hash: Poseidon.hash([
        element.key,
        element.value.data,
        element.value.kind,
      ]),
      count: Field(1),
    });
  }
 
  static merge(
    state1: RedactedMinaNFTMapState,
    state2: RedactedMinaNFTMapState
  ) {
    Metadata.assertEquals(state1.originalRoot, state2.originalRoot);
    Metadata.assertEquals(state1.redactedRoot, state2.redactedRoot);
 
    return new RedactedMinaNFTMapState({
      originalRoot: state1.originalRoot,
      redactedRoot: state1.redactedRoot,
      hash: state1.hash.add(state2.hash),
      count: state1.count.add(state2.count),
    });
  }
 
  static assertEquals(
    state1: RedactedMinaNFTMapState,
    state2: RedactedMinaNFTMapState
  ) {
    Metadata.assertEquals(state1.originalRoot, state2.originalRoot);
    Metadata.assertEquals(state1.redactedRoot, state2.redactedRoot);
    state1.hash.assertEquals(state2.hash);
    state1.count.assertEquals(state2.count);
  }
}
 
const RedactedMinaNFTMapCalculation = ZkProgram({
  name: "RedactedMinaNFTMapCalculation",
  publicInput: RedactedMinaNFTMapState,
 
  methods: {
    create: {
      privateInputs: [MapElement, MetadataWitness, MetadataWitness],
 
      async method(
        state: RedactedMinaNFTMapState,
        element: MapElement,
        originalWitness: MetadataWitness,
        redactedWitness: MetadataWitness
      ) {
        const computedState = RedactedMinaNFTMapState.create(
          element,
          originalWitness,
          redactedWitness
        );
        RedactedMinaNFTMapState.assertEquals(computedState, state);
      },
    },
 
    merge: {
      privateInputs: [SelfProof, SelfProof],
 
      async method(
        newState: RedactedMinaNFTMapState,
        proof1: SelfProof<RedactedMinaNFTMapState, void>,
        proof2: SelfProof<RedactedMinaNFTMapState, void>
      ) {
        proof1.verify();
        proof2.verify();
        const computedState = RedactedMinaNFTMapState.merge(
          proof1.publicInput,
          proof2.publicInput
        );
        RedactedMinaNFTMapState.assertEquals(computedState, newState);
      },
    },
  },
});
 
class RedactedMinaNFTMapStateProof extends ZkProgram.Proof(
  RedactedMinaNFTMapCalculation
) {}