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
//! Signer side of the protocol //! //! # Note //! This **does not** include **any** networking code to actually accept the //! request for protocol initiation. Also, the request for protocol initiation //! is neither defined nor implemented by this crate. use curve25519_dalek::{constants::RISTRETTO_BASEPOINT_POINT, scalar::Scalar}; use rand::OsRng; use Error::WiredScalarMalformed; /// For managing the signer side response to incoming requests for blind /// signatures. How the actual requests come in is orthogonal to this crate. pub struct BlindSession { k: Scalar, } impl BlindSession { /// Initiate a new signer side session to create a blind signature for /// a requester. /// /// # Returns /// /// * Ok( ([u8; 32], BlindSession) ) on success, with the [u8; 32] being the /// value R' for sending to the requester, and the BlindSession struct /// supporting the sign_ep() method for completing the protocol (upon the /// receipt of the E' response from the requester). /// /// * Err(::Error) variant on failure, which is only due to the /// failure to initiate the internal random number generator. /// /// # Mathematics /// /// * R' = kP /// * k = A randomly generated scalar by the signer /// * P = An ECC Generator Point pub fn new() -> ::Result<([u8; 32], Self)> { let mut rng = OsRng::new()?; let k = Scalar::random(&mut rng); let rp = (k * RISTRETTO_BASEPOINT_POINT).compress().to_bytes(); Ok((rp, Self { k })) } /// Consumes the session and returns the generated blind signature. /// /// # Arguments /// /// * 'ep' - A reference to a 32 byte scalar represented as a [u8; 32]. This /// scalar is received from the requester in some manner. /// /// * 'xs' - The private key componenet of the associated BlindKeypair /// component, in internal Scalar form. This is used for creating signatures /// which can be authenticated with the associated public key. /// /// # Returns /// /// * Ok([u8; 32]) on success, representing the completed blind signature /// value S'. /// /// * Err(errors::BlindErrors) variant on error. Only errors if the /// requester provided a malformed scalar value ep. /// /// # Mathematics /// /// * S' = Xs*e' + k /// * e' = requester calculated e' value, received by signer /// * k = randomly generated number by the signer pub fn sign_ep(self, ep: &[u8; 32], xs: Scalar) -> ::Result<[u8; 32]> { Ok( (xs * Scalar::from_canonical_bytes(*ep).ok_or(WiredScalarMalformed)? + self.k) .to_bytes(), ) } }