1use core::fmt::{Debug};
16
17use curve25519_dalek::constants;
18use curve25519_dalek::ristretto::{CompressedRistretto,RistrettoPoint};
19use curve25519_dalek::scalar::Scalar;
20
21use super::*;
22use crate::context::{SigningTranscript,SigningContext};
23
24
25pub const SIGNATURE_LENGTH: usize = 64;
29
30#[allow(non_snake_case)]
35#[derive(Clone, Copy, Eq, PartialEq)]
36pub struct Signature {
37 pub (crate) R: CompressedRistretto,
47
48 pub (crate) s: Scalar,
58}
59
60impl Debug for Signature {
61 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
62 write!(f, "Signature( R: {:?}, s: {:?} )", &self.R, &self.s)
63 }
64}
65
66pub(crate) fn check_scalar(bytes: [u8; 32]) -> SignatureResult<Scalar> {
67 if bytes[31] & 0b11110000 == 0 {
76 #[allow(deprecated)] return Ok(Scalar::from_bits(bytes))
78 }
79
80 crate::scalar_from_canonical_bytes(bytes).ok_or(SignatureError::ScalarFormatError)
81}
82
83impl Signature {
84 const DESCRIPTION : &'static str = "A 64 byte Ristretto Schnorr signature";
85 #[inline]
94 pub fn to_bytes(&self) -> [u8; SIGNATURE_LENGTH] {
95 let mut bytes: [u8; SIGNATURE_LENGTH] = [0u8; SIGNATURE_LENGTH];
96 bytes[..32].copy_from_slice(&self.R.as_bytes()[..]);
97 bytes[32..].copy_from_slice(&self.s.as_bytes()[..]);
98 bytes[63] |= 128;
99 bytes
100 }
101
102 #[inline]
117 pub fn from_bytes(bytes: &[u8]) -> SignatureResult<Signature> {
118 if bytes.len() != SIGNATURE_LENGTH {
119 return Err(SignatureError::BytesLengthError {
120 name: "Signature",
121 description: Signature::DESCRIPTION,
122 length: SIGNATURE_LENGTH
123 });
124 }
125
126 let mut lower: [u8; 32] = [0u8; 32];
127 let mut upper: [u8; 32] = [0u8; 32];
128 lower.copy_from_slice(&bytes[..32]);
129 upper.copy_from_slice(&bytes[32..]);
130 if upper[31] & 128 == 0 {
131 return Err(SignatureError::NotMarkedSchnorrkel);
132 }
133 upper[31] &= 127;
134
135 Ok(Signature{ R: CompressedRistretto(lower), s: check_scalar(upper) ? })
136 }
137
138 #[cfg(feature = "preaudit_deprecated")]
141 #[inline]
142 pub fn from_bytes_not_distinguished_from_ed25519(bytes: &[u8]) -> SignatureResult<Signature> {
143 if bytes.len() != SIGNATURE_LENGTH {
144 return Err(SignatureError::BytesLengthError {
145 name: "Signature",
146 description: Signature::DESCRIPTION,
147 length: SIGNATURE_LENGTH
148 });
149 }
150 let mut bytes0: [u8; SIGNATURE_LENGTH] = [0u8; SIGNATURE_LENGTH];
151 bytes0.copy_from_slice(bytes);
152 bytes0[63] |= 128;
153 Signature::from_bytes(&bytes0[..])
154 }
155}
156
157serde_boilerplate!(Signature);
158
159
160impl SecretKey {
163 #[allow(non_snake_case)]
175 pub fn sign<T: SigningTranscript>(&self, mut t: T, public_key: &PublicKey) -> Signature
176 {
177 t.proto_name(b"Schnorr-sig");
178 t.commit_point(b"sign:pk",public_key.as_compressed());
179
180 let mut r = t.witness_scalar(b"signing",&[&self.nonce]); let R = (&r * constants::RISTRETTO_BASEPOINT_TABLE).compress();
182
183 t.commit_point(b"sign:R",&R);
184
185 let k: Scalar = t.challenge_scalar(b"sign:c"); let s: Scalar = k * self.key + r;
187
188 zeroize::Zeroize::zeroize(&mut r);
189
190 Signature{ R, s }
191 }
192
193 pub fn sign_doublecheck<T>(&self, t: T, public_key: &PublicKey) -> SignatureResult<Signature>
195 where T: SigningTranscript+Clone
196 {
197 let sig = self.sign(t.clone(),public_key);
198 let sig = Signature::from_bytes(& sig.to_bytes()) ?;
199 PublicKey::from_bytes(& public_key.to_bytes()) ?
200 .verify(t,&sig).map(|()| sig)
201 }
202
203 pub fn sign_simple(&self, ctx: &[u8], msg: &[u8], public_key: &PublicKey) -> Signature
205 {
206 let t = SigningContext::new(ctx).bytes(msg);
207 self.sign(t,public_key)
208 }
209
210 pub fn sign_simple_doublecheck(&self, ctx: &[u8], msg: &[u8], public_key: &PublicKey)
212 -> SignatureResult<Signature>
213 {
214 let t = SigningContext::new(ctx).bytes(msg);
215 let sig = self.sign(t,public_key);
216 let sig = Signature::from_bytes(& sig.to_bytes()) ?;
217 PublicKey::from_bytes(& public_key.to_bytes()) ?
218 .verify_simple(ctx,msg,&sig).map(|()| sig)
219 }
220}
221
222
223impl PublicKey {
224 #[allow(non_snake_case)]
230 pub fn verify<T: SigningTranscript>(&self, mut t: T, signature: &Signature)
231 -> SignatureResult<()>
232 {
233 let A: &RistrettoPoint = self.as_point();
234
235 t.proto_name(b"Schnorr-sig");
236 t.commit_point(b"sign:pk",self.as_compressed());
237 t.commit_point(b"sign:R",&signature.R);
238
239 let k: Scalar = t.challenge_scalar(b"sign:c"); let R = RistrettoPoint::vartime_double_scalar_mul_basepoint(&k, &(-A), &signature.s);
241
242 if R.compress() == signature.R { Ok(()) } else { Err(SignatureError::EquationFalse) }
243 }
244
245 pub fn verify_simple(&self, ctx: &[u8], msg: &[u8], signature: &Signature)
247 -> SignatureResult<()>
248 {
249 let t = SigningContext::new(ctx).bytes(msg);
250 self.verify(t,signature)
251 }
252
253 #[cfg(feature = "preaudit_deprecated")]
255 #[allow(non_snake_case)]
256 pub fn verify_simple_preaudit_deprecated(&self, ctx: &'static [u8], msg: &[u8], sig: &[u8])
257 -> SignatureResult<()>
258 {
259 let t = SigningContext::new(ctx).bytes(msg);
260
261 if let Ok(signature) = Signature::from_bytes(sig) {
262 return self.verify(t,&signature);
263 }
264
265 let signature = Signature::from_bytes_not_distinguished_from_ed25519(sig) ?;
266
267 let mut t = merlin::Transcript::new(ctx);
268 t.append_message(b"sign-bytes", msg);
269
270 let A: &RistrettoPoint = self.as_point();
271
272 t.proto_name(b"Schnorr-sig");
273 t.commit_point(b"pk",self.as_compressed());
274 t.commit_point(b"no",&signature.R);
275
276 let k: Scalar = t.challenge_scalar(b""); let R = RistrettoPoint::vartime_double_scalar_mul_basepoint(&k, &(-A), &signature.s);
278
279 if R.compress() == signature.R { Ok(()) } else { Err(SignatureError::EquationFalse) }
280 }
281
282}
283
284
285impl Keypair {
286 pub fn sign<T: SigningTranscript>(&self, t: T) -> Signature
347 {
348 self.secret.sign(t, &self.public)
349 }
350
351 pub fn sign_simple(&self, ctx: &[u8], msg: &[u8]) -> Signature
353 {
354 self.secret.sign_simple(ctx, msg, &self.public)
355 }
356
357 pub fn verify<T: SigningTranscript>(&self, t: T, signature: &Signature) -> SignatureResult<()>
385 {
386 self.public.verify(t, signature)
387 }
388
389 pub fn verify_simple(&self, ctx: &[u8], msg: &[u8], signature: &Signature) -> SignatureResult<()>
391 {
392 self.public.verify_simple(ctx, msg, signature)
393 }
394
395
396 pub fn sign_doublecheck<T>(&self, t: T) -> SignatureResult<Signature>
398 where T: SigningTranscript+Clone
399 {
400 let sig = self.sign(t.clone());
401 let sig = Signature::from_bytes(& sig.to_bytes()) ?;
402 PublicKey::from_bytes(& self.public.to_bytes()) ?
403 .verify(t,&sig).map(|()| sig)
404 }
405
406 pub fn sign_simple_doublecheck(&self, ctx: &[u8], msg: &[u8])
408 -> SignatureResult<Signature>
409 {
410 let t = SigningContext::new(ctx).bytes(msg);
411 let sig = self.sign(t);
412 let sig = Signature::from_bytes(& sig.to_bytes()) ?;
413 PublicKey::from_bytes(& self.public.to_bytes()) ?
414 .verify_simple(ctx,msg,&sig).map(|()| sig)
415 }
416
417}
418
419
420#[cfg(test)]
421mod test {
422 use sha3::Shake128;
423 use curve25519_dalek::digest::{Update};
424
425 use super::super::*;
426
427
428 #[cfg(feature = "getrandom")]
429 #[test]
430 fn sign_verify_bytes() {
431 let good_sig: Signature;
432 let bad_sig: Signature;
433
434 let ctx = signing_context(b"good");
435
436 let good: &[u8] = "test message".as_bytes();
437 let bad: &[u8] = "wrong message".as_bytes();
438
439 let mut csprng = rand_core::OsRng;
440
441 let keypair = Keypair::generate_with(&mut csprng);
442 good_sig = keypair.sign(ctx.bytes(&good));
443 bad_sig = keypair.sign(ctx.bytes(&bad));
444
445 let good_sig = Signature::from_bytes(&good_sig.to_bytes()[..]).unwrap();
446 let bad_sig = Signature::from_bytes(&bad_sig.to_bytes()[..]).unwrap();
447
448 assert!(keypair.verify(ctx.bytes(&good), &good_sig).is_ok(),
449 "Verification of a valid signature failed!");
450 assert!(!keypair.verify(ctx.bytes(&good), &bad_sig).is_ok(),
451 "Verification of a signature on a different message passed!");
452 assert!(!keypair.verify(ctx.bytes(&bad), &good_sig).is_ok(),
453 "Verification of a signature on a different message passed!");
454 assert!(!keypair.verify(signing_context(b"bad").bytes(&good), &good_sig).is_ok(),
455 "Verification of a signature on a different message passed!");
456 }
457
458 #[cfg(feature = "getrandom")]
459 #[test]
460 fn sign_verify_xof() {
461 let good_sig: Signature;
462 let bad_sig: Signature;
463
464 let ctx = signing_context(b"testing testing 1 2 3");
465
466 let good: &[u8] = b"test message";
467 let bad: &[u8] = b"wrong message";
468
469 let prehashed_good: Shake128 = Shake128::default().chain(good);
470 let prehashed_bad: Shake128 = Shake128::default().chain(bad);
471 let mut csprng = rand_core::OsRng;
474
475 let keypair = Keypair::generate_with(&mut csprng);
476 good_sig = keypair.sign(ctx.xof(prehashed_good.clone()));
477 bad_sig = keypair.sign(ctx.xof(prehashed_bad.clone()));
478
479 let good_sig_d = Signature::from_bytes(&good_sig.to_bytes()[..]).unwrap();
480 let bad_sig_d = Signature::from_bytes(&bad_sig.to_bytes()[..]).unwrap();
481 assert_eq!(good_sig, good_sig_d);
482 assert_eq!(bad_sig, bad_sig_d);
483
484 assert!(keypair.verify(ctx.xof(prehashed_good.clone()), &good_sig).is_ok(),
485 "Verification of a valid signature failed!");
486 assert!(! keypair.verify(ctx.xof(prehashed_good.clone()), &bad_sig).is_ok(),
487 "Verification of a signature on a different message passed!");
488 assert!(! keypair.verify(ctx.xof(prehashed_bad.clone()), &good_sig).is_ok(),
489 "Verification of a signature on a different message passed!");
490 assert!(! keypair.verify(signing_context(b"oops").xof(prehashed_good), &good_sig).is_ok(),
491 "Verification of a signature on a different message passed!");
492 }
493
494 #[cfg(feature = "preaudit_deprecated")]
495 #[test]
496 fn can_verify_know_preaudit_deprecated_message() {
497 use hex_literal::hex;
498 const SIGNING_CTX : &'static [u8] = b"substrate";
499 let message = b"Verifying that I am the owner of 5G9hQLdsKQswNPgB499DeA5PkFBbgkLPJWkkS6FAM6xGQ8xD. Hash: 221455a3\n";
500 let public = hex!("b4bfa1f7a5166695eb75299fd1c4c03ea212871c342f2c5dfea0902b2c246918");
501 let public = PublicKey::from_bytes(&public[..]).unwrap();
502 let signature = hex!("5a9755f069939f45d96aaf125cf5ce7ba1db998686f87f2fb3cbdea922078741a73891ba265f70c31436e18a9acd14d189d73c12317ab6c313285cd938453202");
503 assert!( public.verify_simple_preaudit_deprecated(SIGNING_CTX,message,&signature[..]).is_ok() );
504 }
505}