schnorr.rs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. use std::io;
  2. use halo2_gadgets::ecc::chip::FixedPoint;
  3. use pasta_curves::{
  4. group::{ff::Field, Group, GroupEncoding},
  5. pallas,
  6. };
  7. use rand::rngs::OsRng;
  8. use crate::{
  9. crypto::{
  10. constants::{NullifierK, DRK_SCHNORR_DOMAIN},
  11. keypair::{PublicKey, SecretKey},
  12. util::{hash_to_scalar, mod_r_p},
  13. },
  14. util::serial::{Decodable, Encodable},
  15. Result,
  16. };
  17. #[derive(Debug, Clone, PartialEq, Eq)]
  18. pub struct Signature {
  19. commit: pallas::Point,
  20. response: pallas::Scalar,
  21. }
  22. impl Signature {
  23. pub fn dummy() -> Self {
  24. Self { commit: pallas::Point::identity(), response: pallas::Scalar::zero() }
  25. }
  26. }
  27. pub trait SchnorrSecret {
  28. fn sign(&self, message: &[u8]) -> Signature;
  29. }
  30. pub trait SchnorrPublic {
  31. fn verify(&self, message: &[u8], signature: &Signature) -> bool;
  32. }
  33. impl SchnorrSecret for SecretKey {
  34. fn sign(&self, message: &[u8]) -> Signature {
  35. let mask = pallas::Scalar::random(&mut OsRng);
  36. let commit = NullifierK.generator() * mask;
  37. let challenge = hash_to_scalar(DRK_SCHNORR_DOMAIN, &commit.to_bytes(), message);
  38. let response = mask + challenge * mod_r_p(self.0);
  39. Signature { commit, response }
  40. }
  41. }
  42. impl SchnorrPublic for PublicKey {
  43. fn verify(&self, message: &[u8], signature: &Signature) -> bool {
  44. let challenge = hash_to_scalar(DRK_SCHNORR_DOMAIN, &signature.commit.to_bytes(), message);
  45. NullifierK.generator() * signature.response - self.0 * challenge == signature.commit
  46. }
  47. }
  48. impl Encodable for Signature {
  49. fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
  50. let mut len = 0;
  51. len += self.commit.encode(&mut s)?;
  52. len += self.response.encode(s)?;
  53. Ok(len)
  54. }
  55. }
  56. impl Decodable for Signature {
  57. fn decode<D: io::Read>(mut d: D) -> Result<Self> {
  58. Ok(Self { commit: Decodable::decode(&mut d)?, response: Decodable::decode(d)? })
  59. }
  60. }
  61. #[cfg(feature = "serde")]
  62. impl serde::Serialize for Signature {
  63. fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
  64. where
  65. S: serde::Serializer,
  66. {
  67. let mut bytes = vec![];
  68. self.encode(&mut bytes).unwrap();
  69. let hex_repr = hex::encode(&bytes);
  70. serializer.serialize_str(&hex_repr)
  71. }
  72. }
  73. #[cfg(feature = "serde")]
  74. struct SignatureVisitor;
  75. #[cfg(feature = "serde")]
  76. impl<'de> serde::de::Visitor<'de> for SignatureVisitor {
  77. type Value = Signature;
  78. fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
  79. formatter.write_str("hex string")
  80. }
  81. fn visit_str<E>(self, value: &str) -> std::result::Result<Signature, E>
  82. where
  83. E: serde::de::Error,
  84. {
  85. let bytes = hex::decode(value).unwrap();
  86. let mut r = std::io::Cursor::new(bytes);
  87. let decoded: Signature = Signature::decode(&mut r).unwrap();
  88. Ok(decoded)
  89. }
  90. }
  91. #[cfg(feature = "serde")]
  92. impl<'de> serde::Deserialize<'de> for Signature {
  93. fn deserialize<D>(deserializer: D) -> std::result::Result<Signature, D::Error>
  94. where
  95. D: serde::Deserializer<'de>,
  96. {
  97. let bytes = deserializer.deserialize_str(SignatureVisitor).unwrap();
  98. Ok(bytes)
  99. }
  100. }
  101. #[cfg(test)]
  102. mod tests {
  103. use super::*;
  104. #[test]
  105. fn test_schnorr() {
  106. let secret = SecretKey::random(&mut OsRng);
  107. let message = b"Foo bar";
  108. let signature = secret.sign(&message[..]);
  109. let public = PublicKey::from_secret(secret);
  110. assert!(public.verify(&message[..], &signature));
  111. }
  112. }