dhke.rs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. //! Diffie-Hellmann key exchange
  2. use std::ops::Deref;
  3. use bitcoin::hashes::sha256::Hash as Sha256Hash;
  4. use bitcoin::hashes::Hash;
  5. use bitcoin::secp256k1::{
  6. Parity, PublicKey as NormalizedPublicKey, Scalar, Secp256k1, XOnlyPublicKey,
  7. };
  8. use thiserror::Error;
  9. use crate::nuts::nut01::{PublicKey, SecretKey};
  10. use crate::nuts::nut12::ProofDleq;
  11. use crate::nuts::{BlindSignature, Keys, Proof, Proofs};
  12. use crate::secret::Secret;
  13. use crate::util::hex;
  14. use crate::SECP256K1;
  15. const DOMAIN_SEPARATOR: &[u8; 28] = b"Secp256k1_HashToCurve_Cashu_";
  16. /// NUT00 Error
  17. #[derive(Debug, Error)]
  18. pub enum Error {
  19. /// Token could not be validated
  20. #[error("Token not verified")]
  21. TokenNotVerified,
  22. /// No valid point on curve
  23. #[error("No valid point found")]
  24. NoValidPoint,
  25. /// Secp256k1 error
  26. #[error(transparent)]
  27. Secp256k1(#[from] bitcoin::secp256k1::Error),
  28. // TODO: Remove use anyhow
  29. /// Custom Error
  30. #[error("`{0}`")]
  31. Custom(String),
  32. }
  33. /// Deterministically maps a message to a public key point on the secp256k1
  34. /// curve, utilizing a domain separator to ensure uniqueness.
  35. ///
  36. /// For definationn in NUT see [NUT-00](https://github.com/cashubtc/nuts/blob/main/00.md)
  37. pub fn hash_to_curve(message: &[u8]) -> Result<PublicKey, Error> {
  38. let msg_to_hash: Vec<u8> = [DOMAIN_SEPARATOR, message].concat();
  39. let msg_hash: [u8; 32] = Sha256Hash::hash(&msg_to_hash).to_byte_array();
  40. let mut counter: u32 = 0;
  41. while counter < 2_u32.pow(16) {
  42. let mut bytes_to_hash: Vec<u8> = Vec::with_capacity(36);
  43. bytes_to_hash.extend_from_slice(&msg_hash);
  44. bytes_to_hash.extend_from_slice(&counter.to_le_bytes());
  45. let hash: [u8; 32] = Sha256Hash::hash(&bytes_to_hash).to_byte_array();
  46. // Try to parse public key
  47. match XOnlyPublicKey::from_slice(&hash) {
  48. Ok(pk) => {
  49. return Ok(NormalizedPublicKey::from_x_only_public_key(pk, Parity::Even).into())
  50. }
  51. Err(_) => {
  52. counter += 1;
  53. }
  54. }
  55. }
  56. Err(Error::NoValidPoint)
  57. }
  58. /// Convert iterator of [`PublicKey`] to byte array
  59. pub fn hash_e<I>(public_keys: I) -> [u8; 32]
  60. where
  61. I: IntoIterator<Item = PublicKey>,
  62. {
  63. let mut e: String = String::new();
  64. for public_key in public_keys.into_iter() {
  65. let uncompressed: [u8; 65] = public_key.to_uncompressed_bytes();
  66. e.push_str(&hex::encode(uncompressed));
  67. }
  68. Sha256Hash::hash(e.as_bytes()).to_byte_array()
  69. }
  70. /// Blind Message
  71. ///
  72. /// `B_ = Y + rG`
  73. pub fn blind_message(
  74. secret: &[u8],
  75. blinding_factor: Option<SecretKey>,
  76. ) -> Result<(PublicKey, SecretKey), Error> {
  77. let y: PublicKey = hash_to_curve(secret)?;
  78. let r: SecretKey = blinding_factor.unwrap_or_else(SecretKey::generate);
  79. Ok((y.combine(&r.public_key())?.into(), r))
  80. }
  81. /// Unblind Message
  82. ///
  83. /// `C_ - rK`
  84. pub fn unblind_message(
  85. // C_
  86. blinded_key: &PublicKey,
  87. r: &SecretKey,
  88. // K
  89. mint_pubkey: &PublicKey,
  90. ) -> Result<PublicKey, Error> {
  91. let r: Scalar = Scalar::from(r.deref().to_owned());
  92. // a = r * K
  93. let a: PublicKey = mint_pubkey.mul_tweak(&SECP256K1, &r)?.into();
  94. // C_ - a
  95. let a: PublicKey = a.negate(&SECP256K1).into();
  96. Ok(blinded_key.combine(&a)?.into()) // C_ + (-a)
  97. }
  98. /// Construct Proof
  99. pub fn construct_proofs(
  100. promises: Vec<BlindSignature>,
  101. rs: Vec<SecretKey>,
  102. secrets: Vec<Secret>,
  103. keys: &Keys,
  104. ) -> Result<Proofs, Error> {
  105. if (promises.len() != rs.len()) || (promises.len() != secrets.len()) {
  106. tracing::error!(
  107. "Promises: {}, RS: {}, secrets:{}",
  108. promises.len(),
  109. rs.len(),
  110. secrets.len()
  111. );
  112. return Err(Error::Custom(
  113. "Lengths of promises, rs, and secrets must be equal".to_string(),
  114. ));
  115. }
  116. let mut proofs = vec![];
  117. for ((blinded_signature, r), secret) in promises.into_iter().zip(rs).zip(secrets) {
  118. let blinded_c: PublicKey = blinded_signature.c;
  119. let a: PublicKey = keys
  120. .amount_key(blinded_signature.amount)
  121. .ok_or(Error::Custom("Could not get proofs".to_string()))?;
  122. let unblinded_signature: PublicKey = unblind_message(&blinded_c, &r, &a)?;
  123. let dleq = blinded_signature.dleq.map(|d| ProofDleq::new(d.e, d.s, r));
  124. let proof = Proof {
  125. amount: blinded_signature.amount,
  126. keyset_id: blinded_signature.keyset_id,
  127. secret,
  128. c: unblinded_signature,
  129. witness: None,
  130. dleq,
  131. };
  132. proofs.push(proof);
  133. }
  134. Ok(proofs)
  135. }
  136. /// Sign Blinded Message
  137. ///
  138. /// `C_ = k * B_`, where:
  139. /// * `k` is the private key of mint (one for each amount)
  140. /// * `B_` is the blinded message
  141. #[inline]
  142. pub fn sign_message(k: &SecretKey, blinded_message: &PublicKey) -> Result<PublicKey, Error> {
  143. let k: Scalar = Scalar::from(k.deref().to_owned());
  144. Ok(blinded_message.mul_tweak(&SECP256K1, &k)?.into())
  145. }
  146. /// Verify Message
  147. pub fn verify_message(
  148. a: &SecretKey,
  149. unblinded_message: PublicKey,
  150. msg: &[u8],
  151. ) -> Result<(), Error> {
  152. // Y
  153. let y: PublicKey = hash_to_curve(msg)?;
  154. // Compute the expected unblinded message
  155. let expected_unblinded_message: PublicKey = y
  156. .mul_tweak(&Secp256k1::new(), &Scalar::from(*a.deref()))?
  157. .into();
  158. // Compare the unblinded_message with the expected value
  159. if unblinded_message == expected_unblinded_message {
  160. return Ok(());
  161. }
  162. Err(Error::TokenNotVerified)
  163. }
  164. #[cfg(test)]
  165. mod tests {
  166. use std::str::FromStr;
  167. use super::*;
  168. #[test]
  169. fn test_hash_to_curve() {
  170. let secret = "0000000000000000000000000000000000000000000000000000000000000000";
  171. let sec_hex = hex::decode(secret).unwrap();
  172. let y = hash_to_curve(&sec_hex).unwrap();
  173. let expected_y = PublicKey::from_hex(
  174. "024cce997d3b518f739663b757deaec95bcd9473c30a14ac2fd04023a739d1a725",
  175. )
  176. .unwrap();
  177. assert_eq!(y, expected_y);
  178. let secret = "0000000000000000000000000000000000000000000000000000000000000001";
  179. let sec_hex = hex::decode(secret).unwrap();
  180. let y = hash_to_curve(&sec_hex).unwrap();
  181. let expected_y = PublicKey::from_hex(
  182. "022e7158e11c9506f1aa4248bf531298daa7febd6194f003edcd9b93ade6253acf",
  183. )
  184. .unwrap();
  185. assert_eq!(y, expected_y);
  186. // Note that this message will take a few iterations of the loop before finding
  187. // a valid point
  188. let secret = "0000000000000000000000000000000000000000000000000000000000000002";
  189. let sec_hex = hex::decode(secret).unwrap();
  190. let y = hash_to_curve(&sec_hex).unwrap();
  191. let expected_y = PublicKey::from_hex(
  192. "026cdbe15362df59cd1dd3c9c11de8aedac2106eca69236ecd9fbe117af897be4f",
  193. )
  194. .unwrap();
  195. assert_eq!(y, expected_y);
  196. }
  197. #[test]
  198. fn test_hash_e() {
  199. let c = PublicKey::from_str(
  200. "02a9acc1e48c25eeeb9289b5031cc57da9fe72f3fe2861d264bdc074209b107ba2",
  201. )
  202. .unwrap();
  203. let k = PublicKey::from_str(
  204. "020000000000000000000000000000000000000000000000000000000000000001",
  205. )
  206. .unwrap();
  207. let r1 = PublicKey::from_str(
  208. "020000000000000000000000000000000000000000000000000000000000000001",
  209. )
  210. .unwrap();
  211. let r2 = PublicKey::from_str(
  212. "020000000000000000000000000000000000000000000000000000000000000001",
  213. )
  214. .unwrap();
  215. let e = hash_e(vec![r1, r2, k, c]);
  216. let e_hex = hex::encode(e);
  217. assert_eq!(
  218. "a4dc034b74338c28c6bc3ea49731f2a24440fc7c4affc08b31a93fc9fbe6401e",
  219. e_hex
  220. )
  221. }
  222. #[test]
  223. fn test_blind_message() {
  224. let message =
  225. hex::decode("d341ee4871f1f889041e63cf0d3823c713eea6aff01e80f1719f08f9e5be98f6")
  226. .unwrap();
  227. let sec: SecretKey =
  228. SecretKey::from_hex("99fce58439fc37412ab3468b73db0569322588f62fb3a49182d67e23d877824a")
  229. .unwrap();
  230. let (b, r) = blind_message(&message, Some(sec.clone())).unwrap();
  231. assert_eq!(sec, r);
  232. assert_eq!(
  233. b,
  234. PublicKey::from_hex(
  235. "033b1a9737a40cc3fd9b6af4b723632b76a67a36782596304612a6c2bfb5197e6d"
  236. )
  237. .unwrap()
  238. );
  239. let message =
  240. hex::decode("f1aaf16c2239746f369572c0784d9dd3d032d952c2d992175873fb58fae31a60")
  241. .unwrap();
  242. let sec: SecretKey =
  243. SecretKey::from_hex("f78476ea7cc9ade20f9e05e58a804cf19533f03ea805ece5fee88c8e2874ba50")
  244. .unwrap();
  245. let (b, r) = blind_message(&message, Some(sec.clone())).unwrap();
  246. assert_eq!(sec, r);
  247. assert_eq!(
  248. b,
  249. PublicKey::from_hex(
  250. "029bdf2d716ee366eddf599ba252786c1033f47e230248a4612a5670ab931f1763"
  251. )
  252. .unwrap()
  253. );
  254. }
  255. #[test]
  256. fn test_unblind_message() {
  257. let blinded_key = PublicKey::from_hex(
  258. "02a9acc1e48c25eeeb9289b5031cc57da9fe72f3fe2861d264bdc074209b107ba2",
  259. )
  260. .unwrap();
  261. let r =
  262. SecretKey::from_hex("0000000000000000000000000000000000000000000000000000000000000001")
  263. .unwrap();
  264. let a = PublicKey::from_hex(
  265. "020000000000000000000000000000000000000000000000000000000000000001",
  266. )
  267. .unwrap();
  268. let unblinded = unblind_message(&blinded_key, &r, &a).unwrap();
  269. assert_eq!(
  270. PublicKey::from_hex(
  271. "03c724d7e6a5443b39ac8acf11f40420adc4f99a02e7cc1b57703d9391f6d129cd"
  272. )
  273. .unwrap(),
  274. unblinded
  275. );
  276. }
  277. #[test]
  278. fn test_sign_message() {
  279. use super::*;
  280. let message = "test_message";
  281. let sec =
  282. SecretKey::from_hex("0000000000000000000000000000000000000000000000000000000000000001")
  283. .unwrap();
  284. let (blinded_message, _r) = blind_message(message.as_bytes(), Some(sec)).unwrap();
  285. // A
  286. let bob_sec =
  287. SecretKey::from_hex("0000000000000000000000000000000000000000000000000000000000000001")
  288. .unwrap();
  289. // C_
  290. let signed = sign_message(&bob_sec, &blinded_message).unwrap();
  291. assert_eq!(
  292. signed,
  293. PublicKey::from_hex(
  294. "025cc16fe33b953e2ace39653efb3e7a7049711ae1d8a2f7a9108753f1cdea742b"
  295. )
  296. .unwrap()
  297. );
  298. // A
  299. let bob_sec =
  300. SecretKey::from_hex("7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f")
  301. .unwrap();
  302. // C_
  303. let signed = sign_message(&bob_sec, &blinded_message).unwrap();
  304. assert_eq!(
  305. signed,
  306. PublicKey::from_hex(
  307. "027726f0e5757b4202a27198369a3477a17bc275b7529da518fc7cb4a1d927cc0d"
  308. )
  309. .unwrap()
  310. );
  311. }
  312. #[test]
  313. fn test_full_bhke() {
  314. let message =
  315. hex::decode("d341ee4871f1f889041e63cf0d3823c713eea6aff01e80f1719f08f9e5be98f6")
  316. .unwrap();
  317. let alice_sec: SecretKey =
  318. SecretKey::from_hex("99fce58439fc37412ab3468b73db0569322588f62fb3a49182d67e23d877824a")
  319. .unwrap();
  320. let (b, r) = blind_message(&message, Some(alice_sec.clone())).unwrap();
  321. let bob_sec =
  322. SecretKey::from_hex("0000000000000000000000000000000000000000000000000000000000000001")
  323. .unwrap();
  324. // C_
  325. let signed = sign_message(&bob_sec, &b).unwrap();
  326. let unblinded = unblind_message(&signed, &r, &bob_sec.public_key()).unwrap();
  327. assert!(verify_message(&bob_sec, unblinded, &message).is_ok());
  328. }
  329. }