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.

206 lines
5.9 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. extern crate ark_ed_on_bn254;
  2. use ark_ec::{AffineCurve, ProjectiveCurve, TEModelParameters};
  3. use ark_ed_on_bn254::{EdwardsAffine, EdwardsParameters, EdwardsProjective, FqParameters, Fr};
  4. use ark_ff::{fields::PrimeField, BigInteger, Fp256};
  5. use ark_std::{UniformRand, Zero};
  6. use sha2::{Digest, Sha256};
  7. const GX: Fp256<FqParameters> = <EdwardsParameters as TEModelParameters>::AFFINE_GENERATOR_COEFFS.0;
  8. const GY: Fp256<FqParameters> = <EdwardsParameters as TEModelParameters>::AFFINE_GENERATOR_COEFFS.1;
  9. #[macro_use]
  10. extern crate lazy_static;
  11. lazy_static! {
  12. static ref G_AFFINE: EdwardsAffine = EdwardsAffine::new(GX, GY);
  13. pub static ref G: EdwardsProjective = G_AFFINE.into_projective();
  14. }
  15. pub type PublicKey = EdwardsProjective;
  16. pub type Signature = (Fr, Vec<Fr>);
  17. #[derive(Debug, PartialEq)]
  18. pub struct KeyPair {
  19. sk: Fr,
  20. pub pk: PublicKey,
  21. }
  22. pub fn new_key() -> KeyPair {
  23. let mut rng = ark_std::rand::thread_rng();
  24. let sk: Fr = Fr::rand(&mut rng);
  25. // let sk: Fr = UniformRand::rand(&mut rng);
  26. let pk = G.mul(sk.into_repr());
  27. KeyPair { sk, pk }
  28. }
  29. #[allow(clippy::many_single_char_names)]
  30. impl KeyPair {
  31. pub fn key_image(&self) -> EdwardsProjective {
  32. hash_to_point(self.pk).mul(self.sk.into_repr())
  33. }
  34. pub fn sign(&self, ring: Vec<PublicKey>, m: Vec<u8>) -> Signature {
  35. let ring_size = ring.len();
  36. // determine pi (the position of signer's public key in R
  37. let mut pi = 0;
  38. let mut found = false;
  39. // for i in 0..ring_size {
  40. for (i, ring_key) in ring.iter().enumerate() {
  41. if &self.pk == ring_key {
  42. pi = i;
  43. found = true;
  44. break;
  45. }
  46. }
  47. if !found {
  48. // error
  49. println!("key not found in the ring");
  50. }
  51. let mut rng = ark_std::rand::thread_rng();
  52. let a: Fr = Fr::rand(&mut rng);
  53. let mut r: Vec<Fr> = vec![Fr::zero(); ring_size];
  54. // for i \in {1, 2, ..., n} \ {i=pi}
  55. #[allow(clippy::needless_range_loop)]
  56. for i in 0..ring_size {
  57. if i == pi {
  58. continue;
  59. }
  60. r[i] = Fr::rand(&mut rng);
  61. }
  62. let mut c: Vec<Fr> = vec![Fr::zero(); ring_size];
  63. // c_{pi+1}
  64. let pi1 = (pi + 1) % ring_size;
  65. c[pi1] = hash(
  66. &ring,
  67. &m,
  68. G.mul(a.into_repr()),
  69. hash_to_point(ring[pi]).mul(a.into_repr()),
  70. );
  71. let key_image = self.key_image();
  72. // do c_{i+1} from i=pi+1 to pi-1:
  73. for j in 0..(ring_size - 1) {
  74. let i = (pi1 + j) % ring_size;
  75. let i1 = (pi1 + j + 1) % ring_size;
  76. c[i1] = hash(
  77. &ring,
  78. &m,
  79. G.mul(r[i].into_repr()) + ring[i].mul(c[i].into_repr()),
  80. hash_to_point(ring[i]).mul(r[i].into_repr()) + key_image.mul(c[i].into_repr()),
  81. );
  82. println!("i {:?}, {:?}", i, c[i1]);
  83. }
  84. // compute r_pi
  85. r[pi] = a - c[pi] * self.sk;
  86. (c[0], r)
  87. }
  88. }
  89. pub fn verify(
  90. ring: Vec<PublicKey>,
  91. m: Vec<u8>,
  92. key_image: EdwardsProjective,
  93. sig: Signature,
  94. ) -> bool {
  95. let ring_size = ring.len();
  96. let c1 = sig.0;
  97. let r = sig.1;
  98. if ring_size != r.len() {
  99. println!("ERROR"); // TODO
  100. return false;
  101. }
  102. // TODO check that key_image \in G (EC), by l * key_image == 0
  103. let mut c: Vec<Fr> = vec![Fr::zero(); ring_size];
  104. c[0] = c1;
  105. for j in 0..ring_size {
  106. let i = j % ring_size;
  107. let i1 = (j + 1) % ring_size;
  108. c[i1] = hash(
  109. &ring,
  110. &m,
  111. G.mul(r[i].into_repr()) + ring[i].mul(c[i].into_repr()),
  112. hash_to_point(ring[i]).mul(r[i].into_repr()) + key_image.mul(c[i].into_repr()),
  113. );
  114. }
  115. println!("c {:?}\n{:?}", c1, c[0]);
  116. if c1 == c[0] {
  117. return true;
  118. }
  119. false
  120. }
  121. fn hash_to_point(a: EdwardsProjective) -> EdwardsProjective {
  122. // TODO use a proper hash_to_point method
  123. let mut v: Vec<u8> = Vec::new();
  124. v.append(&mut a.into_affine().x.into_repr().to_bytes_le());
  125. v.append(&mut a.into_affine().y.into_repr().to_bytes_le());
  126. let mut hasher = Sha256::new();
  127. hasher.update(v);
  128. let h = hasher.finalize();
  129. let v = Fr::from_le_bytes_mod_order(&h[..]);
  130. G.mul(v.into_repr())
  131. }
  132. fn hash(ring: &[PublicKey], m: &[u8], a: EdwardsProjective, b: EdwardsProjective) -> Fr {
  133. let mut v: Vec<u8> = Vec::new();
  134. for ring_key in ring.iter() {
  135. v.append(&mut ring_key.into_affine().x.into_repr().to_bytes_le());
  136. v.append(&mut ring_key.into_affine().y.into_repr().to_bytes_le());
  137. }
  138. v.append(&mut m.to_vec());
  139. v.append(&mut a.into_affine().x.into_repr().to_bytes_le());
  140. v.append(&mut a.into_affine().y.into_repr().to_bytes_le());
  141. v.append(&mut b.into_affine().x.into_repr().to_bytes_le());
  142. v.append(&mut b.into_affine().y.into_repr().to_bytes_le());
  143. Fr::from_le_bytes_mod_order(&Sha256::new().chain_update(v).finalize())
  144. }
  145. #[cfg(test)]
  146. mod tests {
  147. use super::*;
  148. #[test]
  149. #[allow(non_snake_case)]
  150. fn test_bLSAG() {
  151. let n = 5; // ring size
  152. let pi = 3; // position of prover key in the ring
  153. let k_pi = new_key();
  154. println!("{:?}", k_pi);
  155. // generate other n public keys
  156. let mut ring: Vec<PublicKey> = vec![G.clone(); n];
  157. for i in 0..n {
  158. let k = new_key();
  159. ring[i] = k.pk;
  160. }
  161. // set K_pi
  162. ring[pi] = k_pi.pk;
  163. let m: Vec<u8> = vec![1, 2, 3, 4];
  164. let sig = k_pi.sign(ring.clone(), m.clone());
  165. println!("sig {:?}", sig);
  166. let key_image = k_pi.key_image();
  167. let v = verify(ring.clone(), m.clone(), key_image, sig.clone());
  168. println!("v {:?}", v);
  169. assert!(v);
  170. let m: Vec<u8> = vec![1, 2, 3, 3];
  171. let v = verify(ring, m, key_image, sig);
  172. assert!(!v);
  173. }
  174. }