keypair.rs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2022 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use std::{
  19. convert::TryFrom,
  20. hash::{Hash, Hasher},
  21. str::FromStr,
  22. };
  23. use darkfi_sdk::crypto::constants::NullifierK;
  24. use darkfi_serial::{SerialDecodable, SerialEncodable};
  25. use halo2_gadgets::ecc::chip::FixedPoint;
  26. use pasta_curves::{
  27. arithmetic::CurveAffine,
  28. group::{
  29. ff::{Field, PrimeField},
  30. Curve, Group, GroupEncoding,
  31. },
  32. pallas,
  33. };
  34. use rand::RngCore;
  35. use crate::{
  36. crypto::{address::Address, util::mod_r_p},
  37. Error, Result,
  38. };
  39. #[derive(Copy, Clone, PartialEq, Eq, Debug)]
  40. pub struct Keypair {
  41. pub secret: SecretKey,
  42. pub public: PublicKey,
  43. }
  44. impl Keypair {
  45. pub fn new(secret: SecretKey) -> Self {
  46. let public = PublicKey::from_secret(secret);
  47. Self { secret, public }
  48. }
  49. pub fn random(mut rng: impl RngCore) -> Self {
  50. let secret = SecretKey::random(&mut rng);
  51. Self::new(secret)
  52. }
  53. }
  54. #[derive(Copy, Clone, PartialEq, Eq, Debug, SerialDecodable, SerialEncodable)]
  55. pub struct SecretKey(pub pallas::Base);
  56. impl SecretKey {
  57. pub fn random(mut rng: impl RngCore) -> Self {
  58. let x = pallas::Base::random(&mut rng);
  59. Self(x)
  60. }
  61. pub fn to_bytes(self) -> [u8; 32] {
  62. self.0.to_repr()
  63. }
  64. pub fn from_bytes(bytes: [u8; 32]) -> Result<Self> {
  65. match pallas::Base::from_repr(bytes).into() {
  66. Some(k) => Ok(Self(k)),
  67. None => Err(Error::SecretKeyFromBytes),
  68. }
  69. }
  70. pub fn inner(&self) -> pallas::Base {
  71. self.0
  72. }
  73. }
  74. impl From<pallas::Base> for SecretKey {
  75. fn from(x: pallas::Base) -> Self {
  76. Self(x)
  77. }
  78. }
  79. impl FromStr for SecretKey {
  80. type Err = crate::Error;
  81. /// Tries to create a `SecretKey` instance from a base58 encoded string.
  82. fn from_str(encoded: &str) -> core::result::Result<Self, crate::Error> {
  83. let decoded = bs58::decode(encoded).into_vec()?;
  84. if decoded.len() != 32 {
  85. return Err(Error::SecretKeyFromStr)
  86. }
  87. Self::from_bytes(decoded.try_into().unwrap())
  88. }
  89. }
  90. #[derive(Copy, Clone, PartialEq, Eq, Debug, SerialDecodable, SerialEncodable)]
  91. pub struct PublicKey(pub pallas::Point);
  92. impl PublicKey {
  93. pub fn random(mut rng: impl RngCore) -> Self {
  94. let p = pallas::Point::random(&mut rng);
  95. Self(p)
  96. }
  97. pub fn from_secret(s: SecretKey) -> Self {
  98. let nfk = NullifierK;
  99. let p = nfk.generator() * mod_r_p(s.0);
  100. Self(p)
  101. }
  102. pub fn to_bytes(self) -> [u8; 32] {
  103. self.0.to_bytes()
  104. }
  105. pub fn from_bytes(bytes: &[u8; 32]) -> Result<Self> {
  106. match pallas::Point::from_bytes(bytes).into() {
  107. Some(k) => Ok(Self(k)),
  108. None => Err(Error::PublicKeyFromBytes),
  109. }
  110. }
  111. pub fn x(&self) -> pallas::Base {
  112. *self.0.to_affine().coordinates().unwrap().x()
  113. }
  114. pub fn y(&self) -> pallas::Base {
  115. *self.0.to_affine().coordinates().unwrap().y()
  116. }
  117. pub fn xy(&self) -> (pallas::Base, pallas::Base) {
  118. let coords = self.0.to_affine().coordinates().unwrap();
  119. (*coords.x(), *coords.y())
  120. }
  121. }
  122. impl Hash for PublicKey {
  123. fn hash<H: Hasher>(&self, state: &mut H) {
  124. let bytes = self.0.to_affine().to_bytes();
  125. bytes.hash(state);
  126. }
  127. }
  128. impl FromStr for PublicKey {
  129. type Err = crate::Error;
  130. /// Tries to create a `PublicKey` instance from a base58 encoded string.
  131. fn from_str(encoded: &str) -> core::result::Result<Self, crate::Error> {
  132. let decoded = bs58::decode(encoded).into_vec()?;
  133. if decoded.len() != 32 {
  134. return Err(Error::PublicKeyFromStr)
  135. }
  136. Self::from_bytes(&decoded.try_into().unwrap())
  137. }
  138. }
  139. impl From<pallas::Point> for PublicKey {
  140. fn from(x: pallas::Point) -> Self {
  141. Self(x)
  142. }
  143. }
  144. impl TryFrom<Address> for PublicKey {
  145. type Error = Error;
  146. fn try_from(address: Address) -> Result<Self> {
  147. let mut bytes = [0u8; 32];
  148. bytes.copy_from_slice(&address.0[1..33]);
  149. Self::from_bytes(&bytes)
  150. }
  151. }