Support multiple BLS implementations (#1335)

## Issue Addressed

NA

## Proposed Changes

- Refactor the `bls` crate to support multiple BLS "backends" (e.g., milagro, blst, etc).
- Removes some duplicate, unused code in `common/rest_types/src/validator.rs`.
- Removes the old "upgrade legacy keypairs" functionality (these were unencrypted keys that haven't been supported for a few testnets, no one should be using them anymore).

## Additional Info

Most of the files changed are just inconsequential changes to function names.

## TODO

- [x] Optimization levels
- [x] Infinity point: https://github.com/supranational/blst/issues/11
- [x] Ensure milagro *and* blst are tested via CI
- [x] What to do with unsafe code?
- [x] Test infinity point in signature sets
This commit is contained in:
Paul Hauner
2020-07-25 02:03:18 +00:00
parent 21bcc8848d
commit b73c497be2
117 changed files with 3009 additions and 2463 deletions

View File

@@ -10,7 +10,7 @@ use crate::Uuid;
use aes_ctr::stream_cipher::generic_array::GenericArray;
use aes_ctr::stream_cipher::{NewStreamCipher, SyncStreamCipher};
use aes_ctr::Aes128Ctr as AesCtr;
use bls::{Keypair, PublicKey, SecretHash, SecretKey};
use bls::{Keypair, SecretKey, ZeroizeHash};
use eth2_key_derivation::PlainText;
use hmac::Hmac;
use pbkdf2::pbkdf2;
@@ -21,7 +21,6 @@ use scrypt::{
};
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use ssz::DecodeError;
use std::io::{Read, Write};
/// The byte-length of a BLS secret key.
@@ -58,7 +57,7 @@ pub const HASH_SIZE: usize = 32;
pub enum Error {
InvalidSecretKeyLen { len: usize, expected: usize },
InvalidPassword,
InvalidSecretKeyBytes(DecodeError),
InvalidSecretKeyBytes(bls::Error),
PublicKeyMismatch,
EmptyPassword,
UnableToSerialize(String),
@@ -147,7 +146,7 @@ impl Keystore {
uuid: Uuid,
path: String,
) -> Result<Self, Error> {
let secret: SecretHash = keypair.sk.as_bytes();
let secret: ZeroizeHash = keypair.sk.serialize();
let (cipher_text, checksum) = encrypt(secret.as_bytes(), password, &kdf, &cipher)?;
@@ -172,7 +171,7 @@ impl Keystore {
},
uuid,
path,
pubkey: keypair.pk.as_hex_string()[2..].to_string(),
pubkey: keypair.pk.to_hex_string()[2..].to_string(),
version: Version::four(),
},
})
@@ -201,7 +200,7 @@ impl Keystore {
let keypair = keypair_from_secret(plain_text.as_bytes())?;
// Verify that the derived `PublicKey` matches `self`.
if keypair.pk.as_hex_string()[2..] != self.json.pubkey {
if keypair.pk.to_hex_string()[2..] != self.json.pubkey {
return Err(Error::PublicKeyMismatch);
}
@@ -258,9 +257,9 @@ impl Keystore {
/// - If `secret.len() != 32`.
/// - If `secret` does not represent a point in the BLS curve.
pub fn keypair_from_secret(secret: &[u8]) -> Result<Keypair, Error> {
let sk = SecretKey::from_bytes(secret).map_err(Error::InvalidSecretKeyBytes)?;
let pk = PublicKey::from_secret_key(&sk);
Ok(Keypair { sk, pk })
let sk = SecretKey::deserialize(secret).map_err(Error::InvalidSecretKeyBytes)?;
let pk = sk.public_key();
Ok(Keypair::from_components(pk, sk))
}
/// Returns `Kdf` used by default when creating keystores.

View File

@@ -6,7 +6,7 @@ mod keystore;
pub mod json_keystore;
pub use bls::SecretHash;
pub use bls::ZeroizeHash;
pub use eth2_key_derivation::PlainText;
pub use keystore::{
decrypt, default_kdf, encrypt, keypair_from_secret, Error, Keystore, KeystoreBuilder, DKLEN,