proof.rs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2022 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. use darkfi_serial::{SerialDecodable, SerialEncodable};
  19. use halo2_proofs::{
  20. plonk,
  21. plonk::{Circuit, SingleVerifier},
  22. poly::commitment::Params,
  23. transcript::{Blake2bRead, Blake2bWrite},
  24. };
  25. use pasta_curves::{pallas, vesta};
  26. use rand::RngCore;
  27. // TODO: this API needs rework. It's not very good.
  28. // keygen_pk() takes a VerifyingKey by value,
  29. // yet ProvingKey also provides get_vk() -> &VerifyingKey
  30. //
  31. // Maybe we should just use the native halo2 types instead of wrapping them.
  32. // We can avoid double creating the vk when we call VerifyingKey::build(), ProvingKey::build()
  33. #[derive(Clone, Debug)]
  34. pub struct VerifyingKey {
  35. pub params: Params<vesta::Affine>,
  36. pub vk: plonk::VerifyingKey<vesta::Affine>,
  37. }
  38. impl VerifyingKey {
  39. pub fn build(k: u32, c: &impl Circuit<pallas::Base>) -> Self {
  40. let params = Params::new(k);
  41. let vk = plonk::keygen_vk(&params, c).unwrap();
  42. VerifyingKey { params, vk }
  43. }
  44. }
  45. #[derive(Clone, Debug)]
  46. pub struct ProvingKey {
  47. pub params: Params<vesta::Affine>,
  48. pub pk: plonk::ProvingKey<vesta::Affine>,
  49. }
  50. impl ProvingKey {
  51. pub fn build(k: u32, c: &impl Circuit<pallas::Base>) -> Self {
  52. let params = Params::new(k);
  53. let vk = plonk::keygen_vk(&params, c).unwrap();
  54. let pk = plonk::keygen_pk(&params, vk, c).unwrap();
  55. ProvingKey { params, pk }
  56. }
  57. }
  58. #[derive(Clone, Default, Debug, PartialEq, Eq, SerialEncodable, SerialDecodable)]
  59. pub struct Proof(Vec<u8>);
  60. impl AsRef<[u8]> for Proof {
  61. fn as_ref(&self) -> &[u8] {
  62. &self.0
  63. }
  64. }
  65. impl Proof {
  66. pub fn create(
  67. pk: &ProvingKey,
  68. circuits: &[impl Circuit<pallas::Base>],
  69. instances: &[pallas::Base],
  70. mut rng: impl RngCore,
  71. ) -> std::result::Result<Self, plonk::Error> {
  72. let mut transcript = Blake2bWrite::<_, vesta::Affine, _>::init(vec![]);
  73. plonk::create_proof(
  74. &pk.params,
  75. &pk.pk,
  76. circuits,
  77. &[&[instances]],
  78. &mut rng,
  79. &mut transcript,
  80. )?;
  81. Ok(Proof(transcript.finalize()))
  82. }
  83. pub fn verify(
  84. &self,
  85. vk: &VerifyingKey,
  86. instances: &[pallas::Base],
  87. ) -> std::result::Result<(), plonk::Error> {
  88. let strategy = SingleVerifier::new(&vk.params);
  89. let mut transcript = Blake2bRead::init(&self.0[..]);
  90. plonk::verify_proof(&vk.params, &vk.vk, strategy, &[&[instances]], &mut transcript)
  91. }
  92. pub fn new(bytes: Vec<u8>) -> Self {
  93. Proof(bytes)
  94. }
  95. }