Skip to content

Commit

Permalink
Replace merlin with Shake128
Browse files Browse the repository at this point in the history
We ran into trouble using merlin with dynamic langauges:
paritytech/schnorrkel-js#12
dalek-cryptography/merlin#44
We only benefit minimally if at all from using merlin here anyways,
so just remove it entirely.

Also merlin is not likely to adapt anything else we noticed as
convenient:
dalek-cryptography/merlin#37
  • Loading branch information
burdges committed Jul 3, 2019
1 parent 5e8b0b7 commit a83cf34
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 36 deletions.
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ version = "0.0.3"
arrayref = "0.3"
rand = "0.4"
ff = { version = "0.4", features = ["derive"] }
# sha3 = "0.8"
sha3 = "0.8"

[dependencies.merlin]
version = "1.1.0"
# features = ["debug-transcript"]
# [dependencies.merlin]
# version = "1.1.0"
## features = ["debug-transcript"]

[dependencies.paired]
version = "0.15"
Expand Down
22 changes: 13 additions & 9 deletions src/delinear.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use ff::{PrimeField, PrimeFieldRepr}; // Field, ScalarEngine, SqrtField, PrimeFieldDecodingError
use pairing::{CurveAffine, CurveProjective}; // Engine, EncodedPoint, GroupDecodingError
use rand::{Rng, thread_rng};
use sha3::{Shake128, digest::{Input,ExtendableOutput,XofReader}};

use std::collections::HashMap;

Expand All @@ -34,7 +35,7 @@ use super::verifiers::verify_with_distinct_messages;
/// should consider a proof-of-possession scheme, which requiees all
/// signers register in advance.
pub struct Delinearized<E: EngineBLS> {
key: ::merlin::Transcript,
key: Shake128,
messages_n_publickeys: HashMap<Message,PublicKey<E>>,
signature: Signature<E>,
}
Expand Down Expand Up @@ -68,16 +69,19 @@ impl<'a,E: EngineBLS> Signed for &'a Delinearized<E> {
}

impl<E: EngineBLS> Delinearized<E> {
pub fn new(key: ::merlin::Transcript) -> Delinearized<E> {
pub fn new(key: Shake128) -> Delinearized<E> {
Delinearized {
key,
messages_n_publickeys: HashMap::new(),
signature: Signature(E::SignatureGroup::zero()),
}
}
pub fn new_keyed(key: &[u8]) -> Delinearized<E> {
let mut t = ::merlin::Transcript::new(b"Delinearised BLS");
t.append_message(b"key",key);
let mut t = Shake128::default();
t.input(b"Delinearised BLS with key:");
let l = key.len() as u64;
t.input(l.to_le_bytes());
t.input(key);
Delinearized::new(t)
}
pub fn new_batched_rng<R: Rng>(mut rng: R) -> Delinearized<E> {
Expand All @@ -95,9 +99,9 @@ impl<E: EngineBLS> Delinearized<E> {
/// our return type here changes.
pub fn mask(&self, publickey: &PublicKey<E>) -> E::Scalar {
let mut t = self.key.clone();
t.append_message(b"",publickey.0.into_affine().into_uncompressed().as_ref());
t.input(publickey.0.into_affine().into_uncompressed().as_ref());
let mut b = [0u8; 16];
t.challenge_bytes(b"",&mut b[..]);
t.xof_result().read(&mut b[..]);
let (x,y) = array_refs!(&b,8,8);
let mut x: <E::Scalar as PrimeField>::Repr = u64::from_le_bytes(*x).into();
let y: <E::Scalar as PrimeField>::Repr = u64::from_le_bytes(*y).into();
Expand Down Expand Up @@ -153,8 +157,8 @@ impl<E: EngineBLS> Delinearized<E> {
// TODO: See https://github.com/dalek-cryptography/merlin/pull/37
pub fn agreement(&self, other: &Delinearized<E>) -> bool {
let mut c = [[0u8; 16]; 2];
self.key.clone().challenge_bytes(b"",&mut c[0]);
other.key.clone().challenge_bytes(b"",&mut c[1]);
self.key.clone().xof_result().read(&mut c[0]);
other.key.clone().xof_result().read(&mut c[1]);
c[0] == c[1]
}

Expand Down Expand Up @@ -182,7 +186,7 @@ type PublicKeyUncompressed<E> = <<<E as EngineBLS>::$group as CurveProjective>::
#[derive(Clone)]
pub struct DelinearizedRepeatedSigners<E: EngineBLS> {
key: ::merlin::Transcript,
key: Shake128,
messages_n_publickeys: HashMap<PublicKeyUncompressed<E>,(Message,PublicKey<E>)>,
signature: Signature<E>,
}
Expand Down
21 changes: 11 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,9 @@ extern crate arrayref;
// #[macro_use]
extern crate ff;

extern crate merlin;
extern crate paired as pairing;
extern crate rand;
// extern crate sha3;
extern crate sha3;

use std::borrow::Borrow;

Expand Down Expand Up @@ -125,15 +124,17 @@ pub struct Message(pub [u8; MESSAGE_SIZE]);

impl Message {
pub fn new(context: &'static [u8], message: &[u8]) -> Message {
// use sha3::{Shake128, digest::{Input,ExtendableOutput,XofReader}};
// let mut h = Shake128::default();
// h.input(self.message.borrow());
// h.input(self.signature.0.into_affine().into_uncompressed().as_ref());
let mut t = ::merlin::Transcript::new(context);
t.append_message(b"", message);
use sha3::{Shake128, digest::{Input,ExtendableOutput,XofReader}};
let mut h = Shake128::default();
h.input(context);
let l = message.len() as u64;
h.input(l.to_le_bytes());
h.input(message);
// let mut t = ::merlin::Transcript::new(context);
// t.append_message(b"", message);
let mut msg = [0u8; MESSAGE_SIZE];
// h.xof_result().read(&mut msg[..]);
t.challenge_bytes(b"", &mut msg);
h.xof_result().read(&mut msg[..]);
// t.challenge_bytes(b"", &mut msg);
Message(msg)
}

Expand Down
34 changes: 21 additions & 13 deletions src/single.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use pairing::{CurveAffine, CurveProjective, EncodedPoint, GroupDecodingError};
use rand::{Rng, thread_rng, SeedableRng, chacha::ChaChaRng};
// use rand::prelude::*; // ThreadRng,thread_rng
// use rand_chacha::ChaChaRng;
use sha3::{Shake128, digest::{Input,ExtendableOutput,XofReader}};

// use std::borrow::{Borrow,BorrowMut};
use std::iter::once;
Expand Down Expand Up @@ -619,7 +620,7 @@ impl<E: EngineBLS> SignedMessage<E> {
E::pairing(g1_one, self.signature.0.into_affine()) == E::pairing(self.publickey.0.into_affine(), message)
}

/// Raw bytes output from a BLS signature regarded as a VRF.
/// Hash output from a BLS signature regarded as a VRF.
///
/// If you are not the signer then you must verify the VRF before calling this method.
///
Expand All @@ -629,17 +630,24 @@ impl<E: EngineBLS> SignedMessage<E> {
/// construction from Theorem 2 on page 32 in appendex C of
/// ["Ouroboros Praos: An adaptively-secure, semi-synchronous proof-of-stake blockchain"](https://eprint.iacr.org/2017/573.pdf)
/// by Bernardo David, Peter Gazi, Aggelos Kiayias, and Alexander Russell.
pub fn make_bytes<Out: Default + AsMut<[u8]>>(&self, context: &'static [u8]) -> Out {
// use sha3::{Shake128, digest::{Input,ExtendableOutput,XofReader}};
// let mut h = Shake128::default();
// h.input(&self.message.0[..]);
// h.input(self.signature.0.into_affine().into_uncompressed().as_ref());
let mut t = ::merlin::Transcript::new(context);
t.append_message(b"msg",&self.message.0[..]);
t.append_message(b"out",self.signature.0.into_affine().into_uncompressed().as_ref());
pub fn vrf_hash<H: Input>(&self, h: &mut H) {
h.input(b"msg");
h.input(&self.message.0[..]);
h.input(b"out");
h.input(self.signature.0.into_affine().into_uncompressed().as_ref());
}

/// Raw bytes output from a BLS signature regarded as a VRF.
///
/// If you are not the signer then you must verify the VRF before calling this method.
///
/// If called with distinct contexts then outputs should be independent.
pub fn make_bytes<Out: Default + AsMut<[u8]>>(&self, context: &[u8]) -> Out {
let mut t = Shake128::default();
t.input(context);
self.vrf_hash(&mut t);
let mut seed = Out::default();
// h.xof_result().read(seed.as_mut());
t.challenge_bytes(b"", seed.as_mut());
t.xof_result().read(seed.as_mut());
seed
}

Expand All @@ -649,7 +657,7 @@ impl<E: EngineBLS> SignedMessage<E> {
/// If you are not the signer then you must verify the VRF before calling this method.
///
/// We expect most users would prefer the less generic `VRFInOut::make_chacharng` method.
pub fn make_rng<R: SeedableRng>(&self, context: &'static [u8]) -> R {
pub fn make_rng<R: SeedableRng>(&self, context: &[u8]) -> R {
R::from_seed(self.make_bytes::<R::Seed>(context))
}
*/
Expand All @@ -665,7 +673,7 @@ impl<E: EngineBLS> SignedMessage<E> {
/// construction from Theorem 2 on page 32 in appendex C of
/// ["Ouroboros Praos: An adaptively-secure, semi-synchronous proof-of-stake blockchain"](https://eprint.iacr.org/2017/573.pdf)
/// by Bernardo David, Peter Gazi, Aggelos Kiayias, and Alexander Russell.
pub fn make_chacharng(&self, context: &'static [u8]) -> ChaChaRng {
pub fn make_chacharng(&self, context: &[u8]) -> ChaChaRng {
// self.make_rng::<ChaChaRng>(context)
// TODO: Remove this ugly hack whenever rand gets updated to 0.5 or later
let bytes = self.make_bytes::<[u8;32]>(context);
Expand Down

0 comments on commit a83cf34

Please sign in to comment.