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
use sodiumoxide;
use sodiumoxide::randombytes;
use sodiumoxide::crypto::sign::ed25519;
use sodiumoxide::crypto::hash::sha256;
use error::{Result, Error};

pub type SignatureHint = [u8; 4];

pub struct Signature {
    sig: ed25519::Signature,
}

pub struct DecoratedSignature {
    hint: SignatureHint,
    signature: Signature,
}

pub struct PublicKey {
    key: ed25519::PublicKey,
}

pub struct SecretKey {
    key: ed25519::SecretKey,
}

impl Signature {
    pub fn len(&self) -> usize {
        self.sig.0.len()
    }

    pub fn to_vec(&self) -> Vec<u8> {
        self.sig.0.to_vec()
    }

    pub fn buf(&self) -> &[u8] {
        &self.sig.0
    }
}

impl DecoratedSignature {
    pub fn new(hint: SignatureHint, signature: Signature) -> DecoratedSignature {
        DecoratedSignature {
            hint: hint,
            signature: signature,
        }
    }

    pub fn hint(&self) -> &SignatureHint {
        &self.hint
    }

    pub fn signature(&self) -> &Signature {
        &self.signature
    }
}

impl PublicKey {
    pub fn from_slice(sb: &[u8]) -> Result<PublicKey> {
        let key = ed25519::PublicKey::from_slice(&sb).ok_or(Error::TBD)?;
        Ok(PublicKey { key: key })
    }

    pub fn to_vec(&self) -> Vec<u8> {
        self.key.0.to_vec()
    }

    pub fn signature_hint(&self) -> SignatureHint {
        let mut hint: [u8; 4] = Default::default();
        let buf = self.key.0;
        let len = buf.len();
        hint.copy_from_slice(&buf[len - 4..len]);
        hint
    }
}

impl SecretKey {
    pub fn to_vec(&self) -> Vec<u8> {
        self.key.0.to_vec()
    }
}

pub fn keypair_from_seed(seed: &[u8]) -> Result<(PublicKey, SecretKey)> {
    let the_seed = ed25519::Seed::from_slice(&seed).ok_or(Error::InvalidSeed)?;
    let (pk, sk) = ed25519::keypair_from_seed(&the_seed);
    let public = PublicKey { key: pk };
    let secret = SecretKey { key: sk };
    Ok((public, secret))
}

pub fn random_bytes(size: usize) -> Vec<u8> {
    randombytes::randombytes(size)
}

pub fn hash(m: &[u8]) -> Vec<u8> {
    let digest = sha256::hash(&m);
    digest.0.to_vec()
}

pub fn sign(m: &[u8], sk: &SecretKey) -> Signature {
    let inner = ed25519::sign_detached(m, &sk.key);
    Signature { sig: inner }
}

pub fn verify(m: &[u8], sig: &Signature, pk: &PublicKey) -> bool {
    ed25519::verify_detached(&sig.sig, m, &pk.key)
}

pub fn init() -> bool {
    sodiumoxide::init()
}