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.

133 lines
4.1 KiB

  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::{bytes::FromBytes, fields::PrimeField, BigInteger, Fp256};
  5. use ark_std::{rand, 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. impl KeyPair {
  30. pub fn key_image(&self) -> EdwardsProjective {
  31. hash_to_point(self.pk).mul(self.sk.into_repr())
  32. }
  33. pub fn sign(&self, ring: Vec<PublicKey>, m: Vec<u8>) -> Signature {
  34. let ring_size = ring.len();
  35. // determine pi (the position of signer's public key in R
  36. let mut pi = 0;
  37. let mut found = false;
  38. for i in 0..ring_size {
  39. if self.pk == ring[i] {
  40. pi = i;
  41. found = true;
  42. break;
  43. }
  44. }
  45. if !found {
  46. // error
  47. println!("key not found in the ring");
  48. }
  49. let mut rng = ark_std::rand::thread_rng();
  50. let a: Fr = Fr::rand(&mut rng);
  51. let mut r: Vec<Fr> = vec![Fr::zero(); ring_size];
  52. // for i \in {1, 2, ..., n} \ {i=pi}
  53. for i in 0..ring_size {
  54. if i == pi {
  55. continue;
  56. }
  57. r[i] = Fr::rand(&mut rng);
  58. }
  59. let mut c: Vec<Fr> = vec![Fr::zero(); ring_size];
  60. // c_{pi+1}
  61. let pi1 = (pi + 1) % ring_size;
  62. c[pi1] = hash(
  63. &ring,
  64. &m,
  65. G.mul(a.into_repr()),
  66. hash_to_point(ring[pi]).mul(a.into_repr()),
  67. );
  68. let key_image = self.key_image();
  69. // do c_{i+1} from i=pi+1 to pi-1:
  70. for j in 0..(ring_size - 1) {
  71. let i = (pi1 + j) % ring_size;
  72. let i1 = (pi1 + j + 1) % ring_size;
  73. c[i1] = hash(
  74. &ring,
  75. &m,
  76. G.mul(r[i].into_repr()) + ring[i].mul(c[i].into_repr()),
  77. hash_to_point(ring[i]).mul(r[i].into_repr()) + key_image.mul(c[i].into_repr()),
  78. );
  79. println!("i {:?}, {:?}", i, c[i1]);
  80. }
  81. // compute r_pi
  82. r[pi] = a - c[pi] * self.sk;
  83. (c[0], r)
  84. }
  85. }
  86. fn hash_to_point(a: EdwardsProjective) -> EdwardsProjective {
  87. // TODO use a proper hash_to_point method
  88. let mut v: Vec<u8> = Vec::new();
  89. v.append(&mut a.into_affine().x.into_repr().to_bytes_le());
  90. v.append(&mut a.into_affine().y.into_repr().to_bytes_le());
  91. let mut hasher = Sha256::new();
  92. hasher.update(v);
  93. let h = hasher.finalize();
  94. let v = Fr::from_le_bytes_mod_order(&h[..]);
  95. G.mul(v.into_repr())
  96. }
  97. fn hash(ring: &Vec<PublicKey>, m: &Vec<u8>, a: EdwardsProjective, b: EdwardsProjective) -> Fr {
  98. let mut v: Vec<u8> = Vec::new();
  99. for i in 0..ring.len() {
  100. v.append(&mut ring[i].into_affine().x.into_repr().to_bytes_le());
  101. v.append(&mut ring[i].into_affine().y.into_repr().to_bytes_le());
  102. }
  103. v.append(&mut m.clone());
  104. v.append(&mut a.into_affine().x.into_repr().to_bytes_le());
  105. v.append(&mut a.into_affine().y.into_repr().to_bytes_le());
  106. v.append(&mut b.into_affine().x.into_repr().to_bytes_le());
  107. v.append(&mut b.into_affine().y.into_repr().to_bytes_le());
  108. Fr::from_le_bytes_mod_order(&Sha256::new().chain_update(v).finalize())
  109. }
  110. #[cfg(test)]
  111. mod tests {
  112. use super::*;
  113. }