You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
3.8 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. use super::errors::NovaError;
  2. use super::traits::{CompressedGroup, Group};
  3. use core::fmt::Debug;
  4. use core::ops::{Add, AddAssign, Mul, MulAssign};
  5. use digest::{ExtendableOutput, Input};
  6. use merlin::Transcript;
  7. use sha3::Shake256;
  8. use std::io::Read;
  9. #[derive(Debug)]
  10. pub struct CommitGens<G: Group> {
  11. gens: Vec<G>,
  12. }
  13. #[derive(Clone, Copy, Debug, PartialEq, Eq)]
  14. pub struct Commitment<G: Group> {
  15. comm: G,
  16. }
  17. #[derive(Clone, Debug, PartialEq, Eq)]
  18. pub struct CompressedCommitment<C: CompressedGroup> {
  19. comm: C,
  20. }
  21. impl<G: Group> CommitGens<G> {
  22. pub fn new(label: &[u8], n: usize) -> Self {
  23. let mut shake = Shake256::default();
  24. shake.input(label);
  25. let mut reader = shake.xof_result();
  26. let mut gens: Vec<G> = Vec::new();
  27. let mut uniform_bytes = [0u8; 64];
  28. for _ in 0..n {
  29. reader.read_exact(&mut uniform_bytes).unwrap();
  30. gens.push(G::from_uniform_bytes(&uniform_bytes).unwrap());
  31. }
  32. CommitGens { gens }
  33. }
  34. }
  35. impl<G: Group> Commitment<G> {
  36. pub fn compress(&self) -> CompressedCommitment<G::CompressedGroupElement> {
  37. CompressedCommitment {
  38. comm: self.comm.compress(),
  39. }
  40. }
  41. }
  42. impl<C: CompressedGroup> CompressedCommitment<C> {
  43. pub fn decompress(&self) -> Result<Commitment<C::GroupElement>, NovaError> {
  44. let comm = self.comm.decompress();
  45. if comm.is_none() {
  46. return Err(NovaError::DecompressionError);
  47. }
  48. Ok(Commitment {
  49. comm: comm.unwrap(),
  50. })
  51. }
  52. }
  53. pub trait CommitTrait<G: Group> {
  54. fn commit(&self, gens: &CommitGens<G>) -> Commitment<G>;
  55. }
  56. impl<G: Group> CommitTrait<G> for [G::Scalar] {
  57. fn commit(&self, gens: &CommitGens<G>) -> Commitment<G> {
  58. assert_eq!(gens.gens.len(), self.len());
  59. Commitment {
  60. comm: G::vartime_multiscalar_mul(self, &gens.gens),
  61. }
  62. }
  63. }
  64. pub trait AppendToTranscriptTrait {
  65. fn append_to_transcript(&self, label: &'static [u8], transcript: &mut Transcript);
  66. }
  67. impl<G: Group> AppendToTranscriptTrait for Commitment<G> {
  68. fn append_to_transcript(&self, label: &'static [u8], transcript: &mut Transcript) {
  69. transcript.append_message(label, self.comm.compress().as_bytes());
  70. }
  71. }
  72. impl<C: CompressedGroup> AppendToTranscriptTrait for CompressedCommitment<C> {
  73. fn append_to_transcript(&self, label: &'static [u8], transcript: &mut Transcript) {
  74. transcript.append_message(label, self.comm.as_bytes());
  75. }
  76. }
  77. impl<'b, G: Group> MulAssign<&'b G::Scalar> for Commitment<G> {
  78. fn mul_assign(&mut self, scalar: &'b G::Scalar) {
  79. let result = (self as &Commitment<G>).comm * scalar;
  80. *self = Commitment { comm: result };
  81. }
  82. }
  83. impl<G: Group> Mul<G::Scalar> for Commitment<G> {
  84. type Output = Commitment<G>;
  85. fn mul(self, scalar: G::Scalar) -> Commitment<G> {
  86. Commitment {
  87. comm: self.comm * scalar,
  88. }
  89. }
  90. }
  91. impl<'b, G: Group> AddAssign<&'b Commitment<G>> for Commitment<G> {
  92. fn add_assign(&mut self, other: &'b Commitment<G>) {
  93. let result = (self as &Commitment<G>).comm + other.comm;
  94. *self = Commitment { comm: result };
  95. }
  96. }
  97. impl<'a, 'b, G: Group> Add<&'b Commitment<G>> for &'a Commitment<G> {
  98. type Output = Commitment<G>;
  99. fn add(self, other: &'b Commitment<G>) -> Commitment<G> {
  100. Commitment {
  101. comm: self.comm + other.comm,
  102. }
  103. }
  104. }
  105. impl<G: Group> AddAssign<Commitment<G>> for Commitment<G> {
  106. fn add_assign(&mut self, rhs: Commitment<G>) {
  107. *self += &rhs;
  108. }
  109. }
  110. impl<'b, G: Group> Add<&'b Commitment<G>> for Commitment<G> {
  111. type Output = Commitment<G>;
  112. fn add(self, rhs: &'b Commitment<G>) -> Commitment<G> {
  113. &self + rhs
  114. }
  115. }
  116. impl<'a, G: Group> Add<Commitment<G>> for &'a Commitment<G> {
  117. type Output = Commitment<G>;
  118. fn add(self, rhs: Commitment<G>) -> Commitment<G> {
  119. self + &rhs
  120. }
  121. }
  122. impl<G: Group> Add<Commitment<G>> for Commitment<G> {
  123. type Output = Commitment<G>;
  124. fn add(self, rhs: Commitment<G>) -> Commitment<G> {
  125. &self + &rhs
  126. }
  127. }