1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
use crate::{ ecmult::{ECMultContext, ECMultGenContext}, field::Field, group::{Affine, Jacobian}, scalar::Scalar, Error, }; const P_MINUS_ORDER: Field = Field::new(0, 0, 0, 1, 0x45512319, 0x50B75FC4, 0x402DA172, 0x2FC9BAEE); const ORDER_AS_FE: Field = Field::new( 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xBAAEDCE6, 0xAF48A03B, 0xBFD25E8C, 0xD0364141, ); impl ECMultContext { pub fn verify_raw( &self, sigr: &Scalar, sigs: &Scalar, pubkey: &Affine, message: &Scalar, ) -> bool { let c; let (sn, u1, u2): (Scalar, Scalar, Scalar); if sigr.is_zero() || sigs.is_zero() { return false; } sn = sigs.inv_var(); u1 = &sn * message; u2 = &sn * sigr; let mut pubkeyj: Jacobian = Jacobian::default(); pubkeyj.set_ge(pubkey); let mut pr: Jacobian = Jacobian::default(); self.ecmult(&mut pr, &pubkeyj, &u2, &u1); if pr.is_infinity() { return false; } c = sigr.b32(); let mut xr: Field = Default::default(); let _ = xr.set_b32(&c); if pr.eq_x_var(&xr) { return true; } if xr >= P_MINUS_ORDER { return false; } xr += ORDER_AS_FE; if pr.eq_x_var(&xr) { return true; } false } pub fn recover_raw( &self, sigr: &Scalar, sigs: &Scalar, rec_id: u8, message: &Scalar, ) -> Result<Affine, Error> { debug_assert!(rec_id < 4); if sigr.is_zero() || sigs.is_zero() { return Err(Error::InvalidSignature); } let brx = sigr.b32(); let mut fx = Field::default(); let overflow = fx.set_b32(&brx); debug_assert!(overflow); if rec_id & 2 > 0 { if fx >= P_MINUS_ORDER { return Err(Error::InvalidSignature); } fx += ORDER_AS_FE; } let mut x = Affine::default(); if !x.set_xo_var(&fx, rec_id & 1 > 0) { return Err(Error::InvalidSignature); } let mut xj = Jacobian::default(); xj.set_ge(&x); let rn = sigr.inv(); let mut u1 = &rn * message; u1 = -u1; let u2 = &rn * sigs; let mut qj = Jacobian::default(); self.ecmult(&mut qj, &xj, &u2, &u1); let mut pubkey = Affine::default(); pubkey.set_gej_var(&qj); if pubkey.is_infinity() { Err(Error::InvalidSignature) } else { Ok(pubkey) } } } impl ECMultGenContext { pub fn sign_raw( &self, seckey: &Scalar, message: &Scalar, nonce: &Scalar, ) -> Result<(Scalar, Scalar, u8), Error> { let mut rp = Jacobian::default(); self.ecmult_gen(&mut rp, nonce); let mut r = Affine::default(); r.set_gej(&rp); r.x.normalize(); r.y.normalize(); let b = r.x.b32(); let mut sigr = Scalar::default(); let overflow = bool::from(sigr.set_b32(&b)); debug_assert!(!sigr.is_zero()); debug_assert!(!overflow); let mut recid = (if overflow { 2 } else { 0 }) | (if r.y.is_odd() { 1 } else { 0 }); let mut n = &sigr * seckey; n += message; let mut sigs = nonce.inv(); sigs *= &n; n.clear(); rp.clear(); r.clear(); if sigs.is_zero() { return Err(Error::InvalidMessage); } if sigs.is_high() { sigs = -sigs; recid ^= 1; } Ok((sigr, sigs, recid)) } }