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.

718 lines
22 KiB

3 years ago
3 years ago
3 years ago
3 years ago
  1. // WARNING still updating the code, it works, but is still in process the refactor.
  2. extern crate rand;
  3. #[macro_use]
  4. extern crate ff;
  5. use ff::*;
  6. use poseidon_rs::Poseidon;
  7. pub type Fr = poseidon_rs::Fr; // alias
  8. #[macro_use]
  9. extern crate arrayref;
  10. extern crate generic_array;
  11. extern crate mimc_rs;
  12. extern crate num;
  13. extern crate num_bigint;
  14. extern crate num_traits;
  15. extern crate rand6;
  16. use rand6::Rng;
  17. use blake2::{Blake2b, Digest};
  18. use mimc_rs::Mimc7;
  19. use std::cmp::min;
  20. use num_bigint::{BigInt, RandBigInt, RandomBits, Sign, ToBigInt};
  21. use num_traits::{One, Zero};
  22. use generic_array::GenericArray;
  23. pub mod utils;
  24. #[macro_use]
  25. extern crate lazy_static;
  26. lazy_static! {
  27. static ref D: Fr = Fr::from_str("168696").unwrap();
  28. static ref D_big: BigInt = BigInt::parse_bytes(b"168696", 10).unwrap();
  29. static ref A: Fr = Fr::from_str("168700").unwrap();
  30. static ref A_big: BigInt = BigInt::parse_bytes(b"168700", 10).unwrap();
  31. pub static ref Q: BigInt = BigInt::parse_bytes(
  32. b"21888242871839275222246405745257275088548364400416034343698204186575808495617",10
  33. )
  34. .unwrap();
  35. // pub static ref Q: Fr = Fr::from_str(
  36. // "21888242871839275222246405745257275088548364400416034343698204186575808495617"
  37. // )
  38. // .unwrap();
  39. static ref B8: Point = Point {
  40. x: Fr::from_str(
  41. "5299619240641551281634865583518297030282874472190772894086521144482721001553",
  42. )
  43. .unwrap(),
  44. y: Fr::from_str(
  45. "16950150798460657717958625567821834550301663161624707787222815936182638968203",
  46. )
  47. .unwrap(),
  48. // z: Fr::one(),
  49. };
  50. static ref ORDER: Fr = Fr::from_str(
  51. "21888242871839275222246405745257275088614511777268538073601725287587578984328",
  52. )
  53. .unwrap();
  54. // SUBORDER = ORDER >> 3
  55. // static ref SUBORDER: Fr = Fr::from_str(
  56. // "i2736030358979909402780800718157159386076813972158567259200215660948447373041",
  57. // )
  58. // .unwrap();
  59. static ref SUBORDER: BigInt = &BigInt::parse_bytes(
  60. b"21888242871839275222246405745257275088614511777268538073601725287587578984328",
  61. 10,
  62. )
  63. .unwrap()
  64. >> 3;
  65. }
  66. #[derive(Clone, Debug)]
  67. pub struct PointProjective {
  68. pub x: Fr,
  69. pub y: Fr,
  70. pub z: Fr,
  71. }
  72. impl PointProjective {
  73. pub fn affine(&self) -> Point {
  74. if self.z.is_zero() {
  75. return Point {
  76. x: Fr::zero(),
  77. y: Fr::zero(),
  78. };
  79. }
  80. let mut zinv = self.z.inverse().unwrap();
  81. let mut x = self.x;
  82. x.mul_assign(&zinv);
  83. let mut y = self.y;
  84. y.mul_assign(&zinv);
  85. Point {
  86. x: x.clone(),
  87. y: y.clone(),
  88. }
  89. }
  90. pub fn add(&self, q: &PointProjective) -> Result<PointProjective, String> {
  91. // add-2008-bbjlp https://hyperelliptic.org/EFD/g1p/auto-twisted-projective.html#doubling-dbl-2008-bbjlp
  92. let mut a = self.z;
  93. a.mul_assign(&q.z);
  94. let mut b = a;
  95. b.square();
  96. let mut c = self.x;
  97. c.mul_assign(&q.x);
  98. let mut d = self.y;
  99. d.mul_assign(&q.y);
  100. let mut e = D.clone();
  101. e.mul_assign(&c);
  102. e.mul_assign(&d);
  103. let mut f = b;
  104. f.sub_assign(&e);
  105. let mut g = b;
  106. g.add_assign(&e);
  107. let mut x1y1 = self.x;
  108. x1y1.add_assign(&self.y);
  109. let mut x2y2 = q.x;
  110. x2y2.add_assign(&q.y);
  111. let mut aux = x1y1;
  112. aux.mul_assign(&x2y2);
  113. aux.sub_assign(&c);
  114. aux.sub_assign(&d);
  115. let mut x3 = a;
  116. x3.mul_assign(&f);
  117. x3.mul_assign(&aux);
  118. let mut ac = A.clone();
  119. ac.mul_assign(&c);
  120. let mut dac = d;
  121. dac.sub_assign(&ac);
  122. let mut y3 = a;
  123. y3.mul_assign(&g);
  124. y3.mul_assign(&dac);
  125. let mut z3 = f;
  126. z3.mul_assign(&g);
  127. Ok(PointProjective {
  128. x: x3.clone(),
  129. y: y3.clone(),
  130. z: z3.clone(),
  131. })
  132. }
  133. }
  134. #[derive(Clone, Debug)]
  135. pub struct Point {
  136. pub x: Fr,
  137. pub y: Fr,
  138. }
  139. impl Point {
  140. pub fn projective(&self) -> PointProjective {
  141. PointProjective {
  142. x: self.x.clone(),
  143. y: self.y.clone(),
  144. z: Fr::one(),
  145. }
  146. }
  147. pub fn mul_scalar(&self, n: &BigInt) -> Result<Point, String> {
  148. let mut r: PointProjective = PointProjective {
  149. x: Fr::zero(),
  150. y: Fr::one(),
  151. z: Fr::one(),
  152. };
  153. let mut exp: PointProjective = self.projective();
  154. let (_, b) = n.to_bytes_le();
  155. for i in 0..n.bits() {
  156. if test_bit(&b, i) {
  157. r = r.add(&exp)?;
  158. }
  159. exp = exp.add(&exp)?;
  160. }
  161. Ok(r.affine())
  162. }
  163. pub fn compress(&self) -> [u8; 32] {
  164. let p = &self;
  165. let mut r: [u8; 32] = [0; 32];
  166. let x_big = BigInt::parse_bytes(to_hex(&p.x).as_bytes(), 16).unwrap();
  167. let y_big = BigInt::parse_bytes(to_hex(&p.y).as_bytes(), 16).unwrap();
  168. let (_, y_bytes) = y_big.to_bytes_le();
  169. let len = min(y_bytes.len(), r.len());
  170. r[..len].copy_from_slice(&y_bytes[..len]);
  171. if &x_big > &(&Q.clone() >> 1) {
  172. r[31] = r[31] | 0x80;
  173. }
  174. r
  175. }
  176. pub fn equals(&self, p: Point) -> bool {
  177. if self.x == p.x && self.y == p.y {
  178. return true;
  179. }
  180. false
  181. }
  182. }
  183. pub fn test_bit(b: &Vec<u8>, i: usize) -> bool {
  184. return b[i / 8] & (1 << (i % 8)) != 0;
  185. }
  186. pub fn decompress_point(bb: [u8; 32]) -> Result<Point, String> {
  187. // https://tools.ietf.org/html/rfc8032#section-5.2.3
  188. let mut sign: bool = false;
  189. let mut b = bb.clone();
  190. if b[31] & 0x80 != 0x00 {
  191. sign = true;
  192. b[31] = b[31] & 0x7F;
  193. }
  194. let y: BigInt = BigInt::from_bytes_le(Sign::Plus, &b[..]);
  195. if y >= Q.clone() {
  196. return Err("y outside the Finite Field over R".to_string());
  197. }
  198. let one: BigInt = One::one();
  199. // x^2 = (1 - y^2) / (a - d * y^2) (mod p)
  200. let den = utils::modinv(
  201. &utils::modulus(
  202. &(&A_big.clone() - utils::modulus(&(&D_big.clone() * (&y * &y)), &Q)),
  203. &Q,
  204. ),
  205. &Q,
  206. )?;
  207. let mut x: BigInt = utils::modulus(&((one - utils::modulus(&(&y * &y), &Q)) * den), &Q);
  208. x = utils::modsqrt(&x, &Q)?;
  209. if sign && !(&x > &(&Q.clone() >> 1)) || (!sign && (&x > &(&Q.clone() >> 1))) {
  210. x = x * -1.to_bigint().unwrap();
  211. }
  212. x = utils::modulus(&x, &Q);
  213. let x_fr: Fr = Fr::from_str(&x.to_string()).unwrap();
  214. let y_fr: Fr = Fr::from_str(&y.to_string()).unwrap();
  215. Ok(Point { x: x_fr, y: y_fr })
  216. }
  217. #[derive(Debug, Clone)]
  218. pub struct Signature {
  219. r_b8: Point,
  220. s: BigInt,
  221. }
  222. impl Signature {
  223. pub fn compress(&self) -> [u8; 64] {
  224. let mut b: Vec<u8> = Vec::new();
  225. b.append(&mut self.r_b8.compress().to_vec());
  226. let (_, s_bytes) = self.s.to_bytes_le();
  227. let mut s_32bytes: [u8; 32] = [0; 32];
  228. let len = min(s_bytes.len(), s_32bytes.len());
  229. s_32bytes[..len].copy_from_slice(&s_bytes[..len]);
  230. b.append(&mut s_32bytes.to_vec());
  231. let mut r: [u8; 64] = [0; 64];
  232. r[..].copy_from_slice(&b[..]);
  233. r
  234. }
  235. }
  236. pub fn decompress_signature(b: &[u8; 64]) -> Result<Signature, String> {
  237. let r_b8_bytes: [u8; 32] = *array_ref!(b[..32], 0, 32);
  238. let s: BigInt = BigInt::from_bytes_le(Sign::Plus, &b[32..]);
  239. let r_b8 = decompress_point(r_b8_bytes);
  240. match r_b8 {
  241. Result::Err(err) => return Err(err.to_string()),
  242. Result::Ok(res) => Ok(Signature {
  243. r_b8: res.clone(),
  244. s: s,
  245. }),
  246. }
  247. }
  248. pub struct PrivateKey {
  249. key: BigInt,
  250. }
  251. impl PrivateKey {
  252. pub fn public(&self) -> Result<Point, String> {
  253. // https://tools.ietf.org/html/rfc8032#section-5.1.5
  254. let pk = B8.mul_scalar(&self.key)?;
  255. Ok(pk.clone())
  256. }
  257. pub fn sign(&self, msg: BigInt) -> Result<Signature, String> {
  258. if msg > Q.clone() {
  259. return Err("msg outside the Finite Field".to_string());
  260. }
  261. // https://tools.ietf.org/html/rfc8032#section-5.1.6
  262. let mut hasher = Blake2b::new();
  263. let (_, sk_bytes) = self.key.to_bytes_be();
  264. hasher.input(sk_bytes);
  265. let mut h = hasher.result(); // h: hash(sk)
  266. // s: h[32:64]
  267. let (_, msg_bytes) = msg.to_bytes_be();
  268. let msgFr: Fr = Fr::from_str(&msg.to_string()).unwrap();
  269. let s = GenericArray::<u8, generic_array::typenum::U32>::from_mut_slice(&mut h[32..64]);
  270. let r_bytes = utils::concatenate_arrays(s, &msg_bytes);
  271. let mut r = BigInt::from_bytes_be(Sign::Plus, &r_bytes[..]);
  272. r = utils::modulus(&r, &SUBORDER);
  273. let r8: Point = B8.mul_scalar(&r)?;
  274. let a = &self.public()?;
  275. let hm_input = vec![r8.x.clone(), r8.y.clone(), a.x.clone(), a.y.clone(), msgFr];
  276. let poseidon = Poseidon::new();
  277. let hm = poseidon.hash(hm_input)?;
  278. let mut s = &self.key << 3;
  279. let hmB = BigInt::parse_bytes(to_hex(&hm).as_bytes(), 16).unwrap();
  280. s = hmB * s;
  281. s = r + s;
  282. s = s % &SUBORDER.clone();
  283. Ok(Signature {
  284. r_b8: r8.clone(),
  285. s: s,
  286. })
  287. }
  288. pub fn sign_schnorr(&self, m: BigInt) -> Result<(Point, BigInt), String> {
  289. // random r
  290. let mut rng = rand6::thread_rng();
  291. let k = rng.gen_biguint(1024).to_bigint().unwrap();
  292. // r = k·G
  293. let r = B8.mul_scalar(&k)?;
  294. // h = H(x, r, m)
  295. let pk = &self.public()?;
  296. let h = schnorr_hash(&pk, m, &r)?;
  297. // s= k+x·h
  298. let s = k + &self.key * &h;
  299. Ok((r, s))
  300. }
  301. }
  302. pub fn schnorr_hash(pk: &Point, msg: BigInt, c: &Point) -> Result<BigInt, String> {
  303. if msg > Q.clone() {
  304. return Err("msg outside the Finite Field".to_string());
  305. }
  306. let msgFr: Fr = Fr::from_str(&msg.to_string()).unwrap();
  307. let hm_input = vec![pk.x.clone(), pk.y.clone(), c.x.clone(), c.y.clone(), msgFr];
  308. let poseidon = Poseidon::new();
  309. let h = poseidon.hash(hm_input)?;
  310. println!("h {:?}", h.to_string());
  311. let hB = BigInt::parse_bytes(to_hex(&h).as_bytes(), 16).unwrap();
  312. Ok(hB)
  313. }
  314. pub fn verify_schnorr(pk: Point, m: BigInt, r: Point, s: BigInt) -> Result<bool, String> {
  315. // sG = s·G
  316. let sg = B8.mul_scalar(&s)?;
  317. // r + h · x
  318. let h = schnorr_hash(&pk, m, &r)?;
  319. let pk_h = pk.mul_scalar(&h)?;
  320. let right = r.projective().add(&pk_h.projective())?;
  321. Ok(sg.equals(right.affine()))
  322. }
  323. pub fn new_key() -> PrivateKey {
  324. // https://tools.ietf.org/html/rfc8032#section-5.1.5
  325. let mut rng = rand6::thread_rng();
  326. let sk_raw = rng.gen_biguint(1024).to_bigint().unwrap();
  327. let mut hasher = Blake2b::new();
  328. let (_, sk_raw_bytes) = sk_raw.to_bytes_be();
  329. hasher.input(sk_raw_bytes);
  330. let mut h = hasher.result();
  331. h[0] = h[0] & 0xF8;
  332. h[31] = h[31] & 0x7F;
  333. h[31] = h[31] | 0x40;
  334. let sk = BigInt::from_bytes_le(Sign::Plus, &h[..]);
  335. PrivateKey { key: sk }
  336. }
  337. pub fn verify(pk: Point, sig: Signature, msg: BigInt) -> bool {
  338. if msg > Q.clone() {
  339. return false;
  340. }
  341. let (_, msg_bytes) = msg.to_bytes_be();
  342. let msgFr: Fr = Fr::from_str(&msg.to_string()).unwrap();
  343. let hm_input = vec![
  344. sig.r_b8.x.clone(),
  345. sig.r_b8.y.clone(),
  346. pk.x.clone(),
  347. pk.y.clone(),
  348. msgFr,
  349. ];
  350. let poseidon = Poseidon::new();
  351. let hm = match poseidon.hash(hm_input) {
  352. Result::Err(_) => return false,
  353. Result::Ok(hm) => hm,
  354. };
  355. let l = match B8.mul_scalar(&sig.s) {
  356. Result::Err(_) => return false,
  357. Result::Ok(l) => l,
  358. };
  359. let hmB = BigInt::parse_bytes(to_hex(&hm).as_bytes(), 16).unwrap();
  360. let r = match sig.r_b8.projective().add(
  361. &pk.mul_scalar(&(8.to_bigint().unwrap() * hmB))
  362. .unwrap()
  363. .projective(),
  364. ) {
  365. Result::Err(_) => return false,
  366. Result::Ok(r) => r,
  367. };
  368. l.equals(r.affine())
  369. }
  370. #[cfg(test)]
  371. mod tests {
  372. use super::*;
  373. extern crate rustc_hex;
  374. use rustc_hex::{FromHex, ToHex};
  375. #[test]
  376. fn test_add_same_point() {
  377. let p: PointProjective = PointProjective {
  378. x: Fr::from_str(
  379. "17777552123799933955779906779655732241715742912184938656739573121738514868268",
  380. )
  381. .unwrap(),
  382. y: Fr::from_str(
  383. "2626589144620713026669568689430873010625803728049924121243784502389097019475",
  384. )
  385. .unwrap(),
  386. z: Fr::one(),
  387. };
  388. let q: PointProjective = PointProjective {
  389. x: Fr::from_str(
  390. "17777552123799933955779906779655732241715742912184938656739573121738514868268",
  391. )
  392. .unwrap(),
  393. y: Fr::from_str(
  394. "2626589144620713026669568689430873010625803728049924121243784502389097019475",
  395. )
  396. .unwrap(),
  397. z: Fr::one(),
  398. };
  399. let res = p.add(&q).unwrap().affine();
  400. assert_eq!(
  401. res.x,
  402. Fr::from_str(
  403. "6890855772600357754907169075114257697580319025794532037257385534741338397365"
  404. )
  405. .unwrap()
  406. );
  407. assert_eq!(
  408. res.y,
  409. Fr::from_str(
  410. "4338620300185947561074059802482547481416142213883829469920100239455078257889"
  411. )
  412. .unwrap()
  413. );
  414. }
  415. #[test]
  416. fn test_add_different_points() {
  417. let p: PointProjective = PointProjective {
  418. x: Fr::from_str(
  419. "17777552123799933955779906779655732241715742912184938656739573121738514868268",
  420. )
  421. .unwrap(),
  422. y: Fr::from_str(
  423. "2626589144620713026669568689430873010625803728049924121243784502389097019475",
  424. )
  425. .unwrap(),
  426. z: Fr::one(),
  427. };
  428. let q: PointProjective = PointProjective {
  429. x: Fr::from_str(
  430. "16540640123574156134436876038791482806971768689494387082833631921987005038935",
  431. )
  432. .unwrap(),
  433. y: Fr::from_str(
  434. "20819045374670962167435360035096875258406992893633759881276124905556507972311",
  435. )
  436. .unwrap(),
  437. z: Fr::one(),
  438. };
  439. let res = p.add(&q).unwrap().affine();
  440. assert_eq!(
  441. res.x,
  442. Fr::from_str(
  443. "7916061937171219682591368294088513039687205273691143098332585753343424131937"
  444. )
  445. .unwrap()
  446. );
  447. assert_eq!(
  448. res.y,
  449. Fr::from_str(
  450. "14035240266687799601661095864649209771790948434046947201833777492504781204499"
  451. )
  452. .unwrap()
  453. );
  454. }
  455. #[test]
  456. fn test_mul_scalar() {
  457. let p: Point = Point {
  458. x: Fr::from_str(
  459. "17777552123799933955779906779655732241715742912184938656739573121738514868268",
  460. )
  461. .unwrap(),
  462. y: Fr::from_str(
  463. "2626589144620713026669568689430873010625803728049924121243784502389097019475",
  464. )
  465. .unwrap(),
  466. };
  467. let res_m = p.mul_scalar(&3.to_bigint().unwrap()).unwrap();
  468. let res_a = p.projective().add(&p.projective()).unwrap();
  469. let res_a = res_a.add(&p.projective()).unwrap().affine();
  470. assert_eq!(res_m.x, res_a.x);
  471. assert_eq!(
  472. res_m.x,
  473. Fr::from_str(
  474. "19372461775513343691590086534037741906533799473648040012278229434133483800898"
  475. )
  476. .unwrap()
  477. );
  478. assert_eq!(
  479. res_m.y,
  480. Fr::from_str(
  481. "9458658722007214007257525444427903161243386465067105737478306991484593958249"
  482. )
  483. .unwrap()
  484. );
  485. let n = BigInt::parse_bytes(
  486. b"14035240266687799601661095864649209771790948434046947201833777492504781204499",
  487. 10,
  488. )
  489. .unwrap();
  490. let res2 = p.mul_scalar(&n).unwrap();
  491. assert_eq!(
  492. res2.x,
  493. Fr::from_str(
  494. "17070357974431721403481313912716834497662307308519659060910483826664480189605"
  495. )
  496. .unwrap()
  497. );
  498. assert_eq!(
  499. res2.y,
  500. Fr::from_str(
  501. "4014745322800118607127020275658861516666525056516280575712425373174125159339"
  502. )
  503. .unwrap()
  504. );
  505. }
  506. // #[test]
  507. // fn test_new_key_sign_verify_mimc_0() {
  508. // let sk = new_key();
  509. // let pk = sk.public().unwrap();
  510. // let msg = 5.to_bigint().unwrap();
  511. // let sig = sk.sign_mimc(msg.clone()).unwrap();
  512. // let v = verify_mimc(pk, sig, msg);
  513. // assert_eq!(v, true);
  514. // }
  515. //
  516. // #[test]
  517. // fn test_new_key_sign_verify_mimc_1() {
  518. // let sk = new_key();
  519. // let pk = sk.public().unwrap();
  520. // let msg = BigInt::parse_bytes(b"123456789012345678901234567890", 10).unwrap();
  521. // let sig = sk.sign_mimc(msg.clone()).unwrap();
  522. // let v = verify_mimc(pk, sig, msg);
  523. // assert_eq!(v, true);
  524. // }
  525. #[test]
  526. fn test_new_key_sign_verify_0() {
  527. let sk = new_key();
  528. let pk = sk.public().unwrap();
  529. let msg = 5.to_bigint().unwrap();
  530. let sig = sk.sign(msg.clone()).unwrap();
  531. let v = verify(pk, sig, msg);
  532. assert_eq!(v, true);
  533. }
  534. #[test]
  535. fn test_new_key_sign_verify_1() {
  536. let sk = new_key();
  537. let pk = sk.public().unwrap();
  538. let msg = BigInt::parse_bytes(b"123456789012345678901234567890", 10).unwrap();
  539. let sig = sk.sign(msg.clone()).unwrap();
  540. let v = verify(pk, sig, msg);
  541. assert_eq!(v, true);
  542. }
  543. #[test]
  544. fn test_point_compress_decompress() {
  545. let p: Point = Point {
  546. x: Fr::from_str(
  547. "17777552123799933955779906779655732241715742912184938656739573121738514868268",
  548. )
  549. .unwrap(),
  550. y: Fr::from_str(
  551. "2626589144620713026669568689430873010625803728049924121243784502389097019475",
  552. )
  553. .unwrap(),
  554. };
  555. let p_comp = p.compress();
  556. assert_eq!(
  557. p_comp[..].to_hex(),
  558. "53b81ed5bffe9545b54016234682e7b2f699bd42a5e9eae27ff4051bc698ce85"
  559. );
  560. let p2 = decompress_point(p_comp).unwrap();
  561. assert_eq!(p.x, p2.x);
  562. assert_eq!(p.y, p2.y);
  563. }
  564. #[test]
  565. fn test_point_decompress0() {
  566. let y_bytes_raw = "b5328f8791d48f20bec6e481d91c7ada235f1facf22547901c18656b6c3e042f"
  567. .from_hex()
  568. .unwrap();
  569. let mut y_bytes: [u8; 32] = [0; 32];
  570. y_bytes.copy_from_slice(&y_bytes_raw);
  571. let p = decompress_point(y_bytes).unwrap();
  572. let expected_px_raw = "b86cc8d9c97daef0afe1a4753c54fb2d8a530dc74c7eee4e72b3fdf2496d2113"
  573. .from_hex()
  574. .unwrap();
  575. let mut e_px_bytes: [u8; 32] = [0; 32];
  576. e_px_bytes.copy_from_slice(&expected_px_raw);
  577. let expected_px: Fr =
  578. Fr::from_str(&BigInt::from_bytes_le(Sign::Plus, &e_px_bytes).to_string()).unwrap();
  579. assert_eq!(&p.x, &expected_px);
  580. }
  581. #[test]
  582. fn test_point_decompress1() {
  583. let y_bytes_raw = "70552d3ff548e09266ded29b33ce75139672b062b02aa66bb0d9247ffecf1d0b"
  584. .from_hex()
  585. .unwrap();
  586. let mut y_bytes: [u8; 32] = [0; 32];
  587. y_bytes.copy_from_slice(&y_bytes_raw);
  588. let p = decompress_point(y_bytes).unwrap();
  589. let expected_px_raw = "30f1635ba7d56f9cb32c3ffbe6dca508a68c7f43936af11a23c785ce98cb3404"
  590. .from_hex()
  591. .unwrap();
  592. let mut e_px_bytes: [u8; 32] = [0; 32];
  593. e_px_bytes.copy_from_slice(&expected_px_raw);
  594. let expected_px: Fr =
  595. Fr::from_str(&BigInt::from_bytes_le(Sign::Plus, &e_px_bytes).to_string()).unwrap();
  596. assert_eq!(&p.x, &expected_px);
  597. }
  598. #[test]
  599. fn test_point_decompress_loop() {
  600. for _ in 0..5 {
  601. let random_bytes = rand6::thread_rng().gen::<[u8; 32]>();
  602. let sk_raw: BigInt = BigInt::from_bytes_le(Sign::Plus, &random_bytes[..]);
  603. let mut hasher = Blake2b::new();
  604. let (_, sk_raw_bytes) = sk_raw.to_bytes_be();
  605. hasher.input(sk_raw_bytes);
  606. let mut h = hasher.result();
  607. h[0] = h[0] & 0xF8;
  608. h[31] = h[31] & 0x7F;
  609. h[31] = h[31] | 0x40;
  610. let sk = BigInt::from_bytes_le(Sign::Plus, &h[..]);
  611. let point = B8.mul_scalar(&sk).unwrap();
  612. let cmp_point = point.compress();
  613. let dcmp_point = decompress_point(cmp_point).unwrap();
  614. assert_eq!(&point.x, &dcmp_point.x);
  615. assert_eq!(&point.y, &dcmp_point.y);
  616. }
  617. }
  618. #[test]
  619. fn test_signature_compress_decompress() {
  620. let sk = new_key();
  621. let pk = sk.public().unwrap();
  622. for i in 0..5 {
  623. let msg_raw = "123456".to_owned() + &i.to_string();
  624. let msg = BigInt::parse_bytes(msg_raw.as_bytes(), 10).unwrap();
  625. let sig = sk.sign(msg.clone()).unwrap();
  626. let compressed_sig = sig.compress();
  627. let decompressed_sig = decompress_signature(&compressed_sig).unwrap();
  628. assert_eq!(&sig.r_b8.x, &decompressed_sig.r_b8.x);
  629. assert_eq!(&sig.r_b8.y, &decompressed_sig.r_b8.y);
  630. assert_eq!(&sig.s, &decompressed_sig.s);
  631. let v = verify(pk.clone(), decompressed_sig, msg);
  632. assert_eq!(v, true);
  633. }
  634. }
  635. #[test]
  636. fn test_schnorr_signature() {
  637. let sk = new_key();
  638. let pk = sk.public().unwrap();
  639. let msg = BigInt::parse_bytes(b"123456789012345678901234567890", 10).unwrap();
  640. let (s, e) = sk.sign_schnorr(msg.clone()).unwrap();
  641. println!("s {:?}", s.x.to_string());
  642. println!("s {:?}", s.y.to_string());
  643. println!("e {:?}", e.to_string());
  644. let verification = verify_schnorr(pk, msg, s, e).unwrap();
  645. assert_eq!(true, verification);
  646. }
  647. }