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.

204 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>) -> Result<Signature, String> {
  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. return Err("key not found in the ring".to_string());
  49. }
  50. let mut rng = ark_std::rand::thread_rng();
  51. let a: Fr = Fr::rand(&mut rng);
  52. let mut r: Vec<Fr> = vec![Fr::zero(); ring_size];
  53. // for i \in {1, 2, ..., n} \ {i=pi}
  54. #[allow(clippy::needless_range_loop)]
  55. for i in 0..ring_size {
  56. if i == pi {
  57. continue;
  58. }
  59. r[i] = Fr::rand(&mut rng);
  60. }
  61. let mut c: Vec<Fr> = vec![Fr::zero(); ring_size];
  62. // c_{pi+1}
  63. let pi1 = (pi + 1) % ring_size;
  64. c[pi1] = hash(
  65. &ring,
  66. &m,
  67. G.mul(a.into_repr()),
  68. hash_to_point(ring[pi]).mul(a.into_repr()),
  69. );
  70. let key_image = self.key_image();
  71. // do c_{i+1} from i=pi+1 to pi-1:
  72. for j in 0..(ring_size - 1) {
  73. let i = (pi1 + j) % ring_size;
  74. let i1 = (pi1 + j + 1) % ring_size;
  75. c[i1] = hash(
  76. &ring,
  77. &m,
  78. G.mul(r[i].into_repr()) + ring[i].mul(c[i].into_repr()),
  79. hash_to_point(ring[i]).mul(r[i].into_repr()) + key_image.mul(c[i].into_repr()),
  80. );
  81. println!("i {:?}, {:?}", i, c[i1]);
  82. }
  83. // compute r_pi
  84. r[pi] = a - c[pi] * self.sk;
  85. Ok((c[0], r))
  86. }
  87. }
  88. pub fn verify(
  89. ring: Vec<PublicKey>,
  90. m: Vec<u8>,
  91. key_image: EdwardsProjective,
  92. sig: Signature,
  93. ) -> bool {
  94. let ring_size = ring.len();
  95. let c1 = sig.0;
  96. let r = sig.1;
  97. if ring_size != r.len() {
  98. return false;
  99. }
  100. // TODO check that key_image \in G (EC), by l * key_image == 0
  101. let mut c: Vec<Fr> = vec![Fr::zero(); ring_size];
  102. c[0] = c1;
  103. for j in 0..ring_size {
  104. let i = j % ring_size;
  105. let i1 = (j + 1) % ring_size;
  106. c[i1] = hash(
  107. &ring,
  108. &m,
  109. G.mul(r[i].into_repr()) + ring[i].mul(c[i].into_repr()),
  110. hash_to_point(ring[i]).mul(r[i].into_repr()) + key_image.mul(c[i].into_repr()),
  111. );
  112. }
  113. println!("c {:?}\n{:?}", c1, c[0]);
  114. if c1 == c[0] {
  115. return true;
  116. }
  117. false
  118. }
  119. fn hash_to_point(a: EdwardsProjective) -> EdwardsProjective {
  120. // TODO use a proper hash_to_point method
  121. let mut v: Vec<u8> = Vec::new();
  122. v.append(&mut a.into_affine().x.into_repr().to_bytes_le());
  123. v.append(&mut a.into_affine().y.into_repr().to_bytes_le());
  124. let mut hasher = Sha256::new();
  125. hasher.update(v);
  126. let h = hasher.finalize();
  127. let v = Fr::from_le_bytes_mod_order(&h[..]);
  128. G.mul(v.into_repr())
  129. }
  130. fn hash(ring: &[PublicKey], m: &[u8], a: EdwardsProjective, b: EdwardsProjective) -> Fr {
  131. let mut v: Vec<u8> = Vec::new();
  132. for ring_key in ring.iter() {
  133. v.append(&mut ring_key.into_affine().x.into_repr().to_bytes_le());
  134. v.append(&mut ring_key.into_affine().y.into_repr().to_bytes_le());
  135. }
  136. v.append(&mut m.to_vec());
  137. v.append(&mut a.into_affine().x.into_repr().to_bytes_le());
  138. v.append(&mut a.into_affine().y.into_repr().to_bytes_le());
  139. v.append(&mut b.into_affine().x.into_repr().to_bytes_le());
  140. v.append(&mut b.into_affine().y.into_repr().to_bytes_le());
  141. Fr::from_le_bytes_mod_order(&Sha256::new().chain_update(v).finalize())
  142. }
  143. #[cfg(test)]
  144. mod tests {
  145. use super::*;
  146. #[test]
  147. #[allow(non_snake_case)]
  148. fn test_bLSAG() {
  149. let n = 5; // ring size
  150. let pi = 3; // position of prover key in the ring
  151. let k_pi = new_key();
  152. println!("{:?}", k_pi);
  153. // generate other n public keys
  154. let mut ring: Vec<PublicKey> = vec![G.clone(); n];
  155. for i in 0..n {
  156. let k = new_key();
  157. ring[i] = k.pk;
  158. }
  159. // set K_pi
  160. ring[pi] = k_pi.pk;
  161. let m: Vec<u8> = vec![1, 2, 3, 4];
  162. let sig = k_pi.sign(ring.clone(), m.clone()).unwrap();
  163. println!("sig {:?}", sig);
  164. let key_image = k_pi.key_image();
  165. let v = verify(ring.clone(), m.clone(), key_image, sig.clone());
  166. println!("v {:?}", v);
  167. assert!(v);
  168. let m: Vec<u8> = vec![1, 2, 3, 3];
  169. let v = verify(ring, m, key_image, sig);
  170. assert!(!v);
  171. }
  172. }