# You will need this repo: # https://github.com/zcash/librustzcash/ # Then compare this code to the file: # librustzcash/zcash_proofs/src/circuit/sapling.rs # What is the LC stuff? # Difference between AllocatedNum and Num # Why BlsScalar vs JJScalar? const: G_VCV: SubgroupPoint G_VCR: SubgroupPoint G_SPEND: SubgroupPoint G_PROOF: SubgroupPoint G_NOTE_COMMIT_R: SubgroupPoint G_NULL: SubgroupPoint CRH_IVK: Blake2sPersonalization NOTE_COMMIT: PedersenPersonalization MERKLE: list PRF_NF: Blake2sPersonalization def value_commit(value: U64, randomness: Scalar) -> Binary: let value_bits: Binary = value as Binary let value: SubgroupPoint = value * G_VCV let rcv: Binary = randomness as Binary let rcv: SubgroupPoint = rcv * G_VCR let cv: SubgroupPoint = value + rcv emit cv return value_bits # The parameters to this function are the same as in: # struct Spend contract input_burn( value: U64, # ValueCommitment.value randomness: Scalar, # ValueCommitment.randomness ak: SubgroupPoint, # from ProofGenerationKey ar: Scalar, nsk: Scalar, # from ProofGenerationKey g_d: SubgroupPoint, # Computed from payment_address commitment_randomness: Scalar, auth_path: list<(Scalar, Bool)>, anchor: Scalar ) -> (SubgroupPoint, SubgroupPoint, SubgroupPoint, Binary): let ak = witness(ak) ak.assert_not_small_order() let ar: Binary = ar as Binary let ar: SubgroupPoint = ar * G_SPEND let rk: SubgroupPoint = ak + ar let nsk: Binary = nsk as Binary let nk: SubgroupPoint = nsk * G_PROOF let mut ivk_preimage: Binary = [] # Must be Binary as well ivk_preimage.extend(ak.repr()) let mut nf_preimage: Binary = [] let nk_repr: Binary = nk.repr() ivk_preimage.extend(nk_repr) nf_preimage.extend(nk_repr) assert len(ivk_preimage) == 512 assert len(nf_preimage) == 256 let mut ivk: Binary = blake2s(ivk_preimage, CRH_IVK) ivk.truncate(Scalar.CAPACITY) let g_d: SubgroupPoint = witness g_d g_d.assert_not_small_order() let pk_d: SubgroupPoint = ivk * g_d let mut note_contents: Binary = [] let (cv: SubgroupPoint, value_bits: Binary) = value_commit(value, randomness) let mut value_num: Num = Num.zero() let mut coeff: Scalar = Scalar.one() for bit in value_bits: value_num = value_num.add_Bool_with_coeff(bit, coeff) coeff = coeff.double() # Is this equivalent? let value_num = value_bits as Num note_contents.extend(value_bits) note_contents.extend(g_d) note_contents.extend(pk_d) assert len(note_contents) == 64 + 256 + 256 let mut cm: SubgroupPoint = pedersen_hash(NOTE_COMMIT, note_contents) let rcm: Binary = commitment_randomness as Binary let rcm: SubgroupPoint = rcm * G_NOTE_COMMIT_R cm += rcm let mut position_bits: Binary = [] let mut cur: Scalar = cm.u for i in range(auth_path.size()): let (node: Scalar, is_right: Bool) = auth_path[i] position_bits.push(is_right) let node: EncryptedNum = EncryptedNum.from(node) print(node) let (left: Binary, right: Binary) = Num.swap_if(is_right, cur, node) let mut preimage: Binary = [] preimage.extend(left) preimage.extend(right) cur = pedersen_hash(MERKLE_TREE[i], preimage).u let rt: SubgroupPoint = EncryptedNum.from(anchor) enforce (cur - rt) * value_num == 0 let position: SubgroupPoint = position_bits * G_NULL let rho: SubgroupPoint = cm + position nf_preimage.extend(rho) assert len(nf_preimage) == 512 let nf: Binary = blake2s(nf_preimage, PRF_NF) emit (rk, cv, rt, nf) contract output_mint( value: U64, randomness: Scalar, g_d: SubgroupPoint, esk: Scalar, pk_d: SubgroupPoint, commitment_randomness: Scalar ) -> (SubgroupPoint, SubgroupPoint, Scalar): let value_bits: Binary = value_commit(value, randomness) let mut note_contents: Binary = [] note_contents.extend(value_bits) let g_d: EdwardsPoint = witness(g_d) g_d.assert_not_small_order() let esk: Binary = esk as Binary let epk: SubgroupPoint = esk * g_d let v_contents: Binary = pk_d.v as Binary let sign_bit: Bool = pk_d.u.is_odd() as Bool note_contents.extend(v_contents) note_contents.push(sign_bit) assert len(note_contents) == 64 + 256 + 256 let mut cm: SubgroupPoint = pedersen_hash(NOTE_COMMIT, note_contents) let rcm: Binary = commitment_randomness as Binary let rcm: SubgroupPoint = rcm * G_NOTE_COMMIT_R cm += rcm let cmu: Scalar = cm.u emit (cv, epk, cmu)