vm_heap.rs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2024 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. //! VM heap type abstractions
  19. use darkfi_sdk::crypto::{
  20. constants::{OrchardFixedBases, MERKLE_DEPTH_ORCHARD},
  21. smt::SMT_FP_DEPTH,
  22. MerkleNode,
  23. };
  24. use halo2_gadgets::ecc::{
  25. chip::EccChip, FixedPoint, FixedPointBaseField, FixedPointShort, NonIdentityPoint, Point,
  26. ScalarFixed,
  27. };
  28. use halo2_proofs::{
  29. circuit::{AssignedCell, Value},
  30. pasta::pallas,
  31. plonk,
  32. };
  33. use log::error;
  34. use crate::{
  35. zkas::{decoder::ZkBinary, types::VarType},
  36. Error::ZkasDecoderError,
  37. Result,
  38. };
  39. /// These represent the witness types outside of the circuit
  40. #[allow(clippy::large_enum_variant)]
  41. #[derive(Clone)]
  42. pub enum Witness {
  43. EcPoint(Value<pallas::Point>),
  44. EcNiPoint(Value<pallas::Point>),
  45. EcFixedPoint(Value<pallas::Point>),
  46. Base(Value<pallas::Base>),
  47. Scalar(Value<pallas::Scalar>),
  48. MerklePath(Value<[MerkleNode; MERKLE_DEPTH_ORCHARD]>),
  49. SparseMerklePath(Value<[pallas::Base; SMT_FP_DEPTH]>),
  50. Uint32(Value<u32>),
  51. Uint64(Value<u64>),
  52. }
  53. impl Witness {
  54. pub fn name(&self) -> &str {
  55. match self {
  56. Self::EcPoint(_) => "EcPoint",
  57. Self::EcNiPoint(_) => "EcNiPoint",
  58. Self::EcFixedPoint(_) => "EcFixedPoint",
  59. Self::Base(_) => "Base",
  60. Self::Scalar(_) => "Scalar",
  61. Self::MerklePath(_) => "MerklePath",
  62. Self::SparseMerklePath(_) => "SparseMerklePath",
  63. Self::Uint32(_) => "Uint32",
  64. Self::Uint64(_) => "Uint64",
  65. }
  66. }
  67. }
  68. /// Helper function for verifiers to generate empty witnesses for
  69. /// a given decoded zkas binary
  70. pub fn empty_witnesses(zkbin: &ZkBinary) -> Result<Vec<Witness>> {
  71. let mut ret = Vec::with_capacity(zkbin.witnesses.len());
  72. for witness in &zkbin.witnesses {
  73. match witness {
  74. VarType::EcPoint => ret.push(Witness::EcPoint(Value::unknown())),
  75. VarType::EcNiPoint => ret.push(Witness::EcNiPoint(Value::unknown())),
  76. VarType::EcFixedPoint => ret.push(Witness::EcFixedPoint(Value::unknown())),
  77. VarType::Base => ret.push(Witness::Base(Value::unknown())),
  78. VarType::Scalar => ret.push(Witness::Scalar(Value::unknown())),
  79. VarType::MerklePath => ret.push(Witness::MerklePath(Value::unknown())),
  80. VarType::SparseMerklePath => ret.push(Witness::SparseMerklePath(Value::unknown())),
  81. VarType::Uint32 => ret.push(Witness::Uint32(Value::unknown())),
  82. VarType::Uint64 => ret.push(Witness::Uint64(Value::unknown())),
  83. x => return Err(ZkasDecoderError(format!("Unsupported witness type: {:?}", x))),
  84. }
  85. }
  86. Ok(ret)
  87. }
  88. /// These represent the witness types inside the circuit
  89. #[allow(clippy::large_enum_variant)]
  90. #[derive(Debug, Clone)]
  91. pub enum HeapVar {
  92. EcPoint(Point<pallas::Affine, EccChip<OrchardFixedBases>>),
  93. EcNiPoint(NonIdentityPoint<pallas::Affine, EccChip<OrchardFixedBases>>),
  94. EcFixedPoint(FixedPoint<pallas::Affine, EccChip<OrchardFixedBases>>),
  95. EcFixedPointShort(FixedPointShort<pallas::Affine, EccChip<OrchardFixedBases>>),
  96. EcFixedPointBase(FixedPointBaseField<pallas::Affine, EccChip<OrchardFixedBases>>),
  97. Base(AssignedCell<pallas::Base, pallas::Base>),
  98. Scalar(ScalarFixed<pallas::Affine, EccChip<OrchardFixedBases>>),
  99. MerklePath(Value<[pallas::Base; MERKLE_DEPTH_ORCHARD]>),
  100. SparseMerklePath(Value<[pallas::Base; SMT_FP_DEPTH]>),
  101. Uint32(Value<u32>),
  102. Uint64(Value<u64>),
  103. }
  104. macro_rules! impl_try_from {
  105. ($variant:ident, $fortype:ty) => {
  106. impl std::convert::TryFrom<HeapVar> for $fortype {
  107. type Error = plonk::Error;
  108. fn try_from(value: HeapVar) -> std::result::Result<Self, Self::Error> {
  109. match value {
  110. HeapVar::$variant(v) => Ok(v),
  111. x => {
  112. error!("Expected {}, but instead got: {:?}", stringify!($variant), x);
  113. Err(plonk::Error::Synthesis)
  114. }
  115. }
  116. }
  117. }
  118. };
  119. }
  120. impl_try_from!(EcPoint, Point<pallas::Affine, EccChip<OrchardFixedBases>>);
  121. impl_try_from!(EcNiPoint, NonIdentityPoint<pallas::Affine, EccChip<OrchardFixedBases>>);
  122. impl_try_from!(EcFixedPoint, FixedPoint<pallas::Affine, EccChip<OrchardFixedBases>>);
  123. impl_try_from!(EcFixedPointShort, FixedPointShort<pallas::Affine, EccChip<OrchardFixedBases>>);
  124. impl_try_from!(EcFixedPointBase, FixedPointBaseField<pallas::Affine, EccChip<OrchardFixedBases>>);
  125. impl_try_from!(Scalar, ScalarFixed<pallas::Affine, EccChip<OrchardFixedBases>>);
  126. impl_try_from!(Base, AssignedCell<pallas::Base, pallas::Base>);
  127. impl_try_from!(Uint32, Value<u32>);
  128. impl_try_from!(MerklePath, Value<[pallas::Base; MERKLE_DEPTH_ORCHARD]>);
  129. impl_try_from!(SparseMerklePath, Value<[pallas::Base; SMT_FP_DEPTH]>);