-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Skalman pok new interface #29
Changes from all commits
fa93daf
ba6a26f
82ef141
db8147f
54f9808
ec0106c
42b6e23
5f193aa
cf94ee1
8d44845
3839aa6
881516f
78b6b2b
c004245
6356a8b
44ebfab
684df14
da4ce55
acc3b73
a482de8
3821a36
2004a0d
ed5223d
e07e15a
7e2aaa3
d54a09f
2281381
a8761d8
628c61e
76873f5
f4d137c
b6ba31d
5460394
5db35d3
e90d26e
8b319e3
2713cd1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,48 @@ | ||
[package] | ||
authors = ["Jack Grigg <[email protected]>", "Jeff Burdges <[email protected]>"] | ||
authors = ["Jack Grigg <[email protected]>", "Jeff Burdges <[email protected]>", "Syed Hosseini <[email protected]>"] | ||
description = "Aggregate BLS-like signatures" | ||
documentation = "https://docs.rs/bls-like" | ||
homepage = "https://github.com/w3f/bls" | ||
license = "MIT/Apache-2.0" | ||
name = "bls-like" | ||
repository = "https://github.com/w3f/bls" | ||
version = "0.1.0" | ||
edition = "2018" | ||
|
||
[dependencies] | ||
arrayref = "0.3" | ||
rand = "0.4" | ||
ff = { version = "0.4", features = ["derive"] } | ||
rand = "0.7" | ||
rand_core = "0.5" | ||
rand_chacha = "0.2" | ||
sha3 = "0.8" | ||
sha2 = "0.9.2" | ||
digest = "0.9.0" | ||
|
||
# [dependencies.merlin] | ||
# version = "1.1.0" | ||
## features = ["debug-transcript"] | ||
#arkwork dependencies | ||
ark-ff = { git = "https://github.com/arkworks-rs/algebra", default-features = false } | ||
ark-ec = { git = "https://github.com/arkworks-rs/algebra", default-features = false } | ||
ark-serialize-derive = { package = "ark-serialize-derive", git = "https://github.com/arkworks-rs/algebra" } | ||
ark-serialize = { git = "https://github.com/arkworks-rs/algebra", default-features = false, features = [ "derive" ] } | ||
ark-bls12-381 = { git = "https://github.com/arkworks-rs/curves", default-features = false, features = [ "curve" ] } | ||
|
||
[dependencies.paired] | ||
version = "0.15" | ||
# git = "https://github.com/filecoin-project/pairing" | ||
|
||
# [dependencies.pairing] | ||
# git = "https://github.com/burdges/pairing" | ||
# branch = "master-hashing-derives_borrows_etc0" | ||
## historical: | ||
## branch = "derives_borrows_etc0" | ||
## git = "https://github.com/mmaker/pairing" | ||
## branch = "master" | ||
# algebra-core = { git = "https://github.com/scipr-lab/zexe" } | ||
# algebra-serialize-derive = { package = "ark-serialize-derive", git = "https://github.com/arkworks-rs/algebra" } | ||
# algebra = { git = "https://github.com/scipr-lab/zexe", features = ["bls12_381"] } | ||
|
||
#for cleaning up secret keys | ||
[dependencies.zeroize] | ||
version = "1.0.0" | ||
default-features = false | ||
features = ["zeroize_derive"] | ||
|
||
[dependencies.serde] | ||
version = "^1.0" | ||
default-features = false | ||
optional = true | ||
|
||
[dev-dependencies] | ||
rand= "0.7.3" | ||
|
||
[dependencies.thiserror] | ||
version = "1.0.10" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
//! ## Implementation of ProofofPossion trait for BLS keys using schnorr sginature | ||
//! ## TODO: I assume this can also moved to pop.rs but for now I put it separately to help reviews | ||
use crate::engine::{EngineBLS}; | ||
use crate::pop::{ProofOfPossessionGenerator, ProofOfPossessionVerifier, SchnorrProof}; | ||
|
||
use crate::single::{SecretKey,PublicKey}; | ||
|
||
use digest::{Digest}; | ||
|
||
use ark_serialize::{CanonicalSerialize}; | ||
use ark_ec::ProjectiveCurve; | ||
|
||
use ark_ff::bytes::{FromBytes, ToBytes}; | ||
|
||
use super::Message; | ||
|
||
// TODO: Delete after migration to secret key model | ||
// pub struct BLSSchnorrProof<E: EngineBLS> : trait B: { | ||
// pub public_key : PublicKey<E>, | ||
// pub proof_of_possession : SchnorrProof<E>, | ||
// } | ||
|
||
/// Generate Schnorr Signature for an arbitrary message using a key ment to use in BLS scheme | ||
trait BLSSchnorrPoPGenerator<E: EngineBLS, H: Digest> : ProofOfPossessionGenerator<E,H> { | ||
/// Produce a secret witness scalar `k`, aka nonce, from hash of | ||
/// H( H(s) | H(public_key)) because our key does not have the | ||
/// randomness redundacy exists in EdDSA secret key. | ||
fn witness_scalar(&self) -> <<E as EngineBLS>::PublicKeyGroup as ProjectiveCurve>::ScalarField; | ||
} | ||
|
||
impl<E: EngineBLS, H: Digest> BLSSchnorrPoPGenerator<E,H> for SecretKey<E> | ||
{ | ||
/// TODO: BROKEN NOW Switch to https://github.com/arkworks-rs/algebra/pull/164/files | ||
fn witness_scalar(&self) -> <<E as EngineBLS>::PublicKeyGroup as ProjectiveCurve>::ScalarField { | ||
let mut secret_key_as_bytes = vec![0; self.into_vartime().0.serialized_size()]; | ||
|
||
let affine_public_key = self.into_public().0.into_affine(); | ||
let mut public_key_as_bytes = vec![0; affine_public_key.serialized_size()]; | ||
|
||
self.into_vartime().0.serialize(&mut secret_key_as_bytes[..]).unwrap(); | ||
affine_public_key.serialize(&mut public_key_as_bytes[..]).unwrap(); | ||
|
||
let secret_key_hash = <H as Digest>::new().chain(secret_key_as_bytes); | ||
let public_key_hash = <H as Digest>::new().chain(public_key_as_bytes); | ||
|
||
let mut scalar_bytes = <H as Digest>::new().chain(secret_key_hash.finalize()).chain(public_key_hash.finalize()).finalize(); | ||
let random_scalar : &mut [u8] = scalar_bytes.as_mut_slice(); | ||
random_scalar[31] &= 31; // BROKEN HACK DO BOT DEPLOY | ||
<<<E as EngineBLS>::PublicKeyGroup as ProjectiveCurve>::ScalarField as FromBytes>::read(&*random_scalar).unwrap() | ||
} | ||
|
||
} | ||
|
||
impl<E: EngineBLS, H: Digest> ProofOfPossessionGenerator<E,H> for SecretKey<E> { | ||
|
||
fn generate_pok(&self, message: Message) -> SchnorrProof<E> { | ||
//First we should figure out the base point in E, I think the secret key trait/struct knows about it. | ||
|
||
//choose random scaler k | ||
//For now we don't we just use a trick similar to Ed25519 | ||
//we use hash of concatination of hash the secret key and the public key | ||
|
||
//schnorr equations | ||
|
||
//R = rG. | ||
//k = H(R|M) | ||
//s = k*private_key + r | ||
// publishing (s, R) verifying that (s*G = H(R|M)*Publickey + R | ||
// instead we actually doing H(s*G - H(R|M)*Publickey|M) == H(R|M) == k | ||
// avoiding one curve addition in expense of a hash. | ||
let mut r = <dyn BLSSchnorrPoPGenerator<E,H>>::witness_scalar(self); | ||
|
||
let mut r_point = <<E as EngineBLS>::PublicKeyGroup as ProjectiveCurve>::prime_subgroup_generator(); | ||
r_point *= r; //todo perhaps we need to mandate E to have a hard coded point | ||
|
||
let mut r_point_as_bytes = Vec::<u8>::new(); | ||
r_point.into_affine().write(&mut r_point_as_bytes).unwrap(); | ||
|
||
let mut k_as_hash = <H as Digest>::new().chain(r_point_as_bytes).chain(message.0).finalize(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. one should include the public key here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. M was public key before but I thought we decided to replace with any arbitary message which can be public key as well. You want public key to be a mandatory part of the message? |
||
let random_scalar : &mut [u8] = k_as_hash.as_mut_slice(); | ||
random_scalar[31] &= 31; // BROKEN HACK DO BOT DEPLOY | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. right this part.. what is the group order again? they just added hash to field, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes they did. It wasn't merged at the time, but I think it should have made it to the master/main now: #32 . |
||
|
||
let k = <<<E as EngineBLS>::PublicKeyGroup as ProjectiveCurve>::ScalarField as FromBytes>::read(&*random_scalar).unwrap(); | ||
let s = (k * self.into_vartime().0) + r; | ||
|
||
::zeroize::Zeroize::zeroize(&mut r); //clear secret key from memory | ||
|
||
(s,k) | ||
} | ||
} | ||
|
||
impl<E: EngineBLS, H: Digest> ProofOfPossessionVerifier<E,H> for PublicKey<E> { | ||
/// verify the validity of schnoor proof for a given publick key by | ||
/// making sure this is equal to zero | ||
/// H(+s G - k Publkey|M) == k | ||
fn verify_pok(&self, message: Message, schnorr_proof: SchnorrProof<E>) -> bool { | ||
let mut schnorr_point = <<E as EngineBLS>::PublicKeyGroup as ProjectiveCurve>::prime_subgroup_generator(); | ||
schnorr_point *= schnorr_proof.0; | ||
let mut k_public_key = self.0; | ||
k_public_key *= -schnorr_proof.1; | ||
schnorr_point += k_public_key; | ||
|
||
let mut schnorr_point_as_bytes = Vec::<u8>::new(); | ||
schnorr_point.into_affine().write(&mut schnorr_point_as_bytes).unwrap(); | ||
|
||
let mut scalar_bytes = <H as Digest>::new().chain(schnorr_point_as_bytes).chain(message.0).finalize(); | ||
let random_scalar = scalar_bytes.as_mut_slice(); | ||
random_scalar[31] &= 31; // BROKEN HACK DO BOT DEPLOY | ||
|
||
let witness_scaler = schnorr_proof.1; | ||
|
||
<<<E as EngineBLS>::PublicKeyGroup as ProjectiveCurve>::ScalarField as FromBytes>::read(&*random_scalar).unwrap() == witness_scaler | ||
|
||
} | ||
|
||
} | ||
|
||
#[cfg(test)] | ||
|
||
mod tests { | ||
#[test] | ||
fn bls_pop_sign() { | ||
use crate::pop::{ProofOfPossessionGenerator}; | ||
use crate::single::{Keypair}; | ||
use crate::engine::{ZBLS}; | ||
use crate::Message; | ||
use rand::{thread_rng}; | ||
use sha2::Sha512; | ||
|
||
let challenge_message = Message::new(b"ctx",b"sign this message, if you really have the secret key"); | ||
let keypair = Keypair::<ZBLS>::generate(thread_rng()); | ||
<dyn ProofOfPossessionGenerator<ZBLS, Sha512>>::generate_pok(&keypair.secret, challenge_message); | ||
} | ||
|
||
#[test] | ||
fn bls_pop_sign_and_verify() | ||
{ | ||
use rand::{thread_rng}; | ||
use sha2::Sha512; | ||
|
||
use crate::single::{Keypair}; | ||
use crate::engine::{ZBLS}; | ||
use crate::Message; | ||
use crate::pop::{ProofOfPossessionGenerator, ProofOfPossessionVerifier}; | ||
|
||
|
||
let challenge_message = Message::new(b"ctx",b"sign this message, if you really have the secret key"); | ||
let keypair = Keypair::<ZBLS>::generate(thread_rng()); | ||
let secret_key = keypair.secret; | ||
let proof_pair = <dyn ProofOfPossessionGenerator<ZBLS, Sha512>>::generate_pok(&secret_key, challenge_message); | ||
assert!(<dyn ProofOfPossessionVerifier<ZBLS, Sha512>>::verify_pok(&keypair.public, challenge_message, proof_pair), "valid pok does not verify") | ||
|
||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm tempted to use a transcript abstraction instead of
Message
like in schnorrkel, ring-vrf, and now the apk crate.Message
made sense for BLS signatures message. And maybe still does. I do not see much point in a schnorr proof.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should maybe make this PoK do both G1 and G2 if we're going that route, no? I guess that's a seperate thing that depends upon only
Engine
. Ugh.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made issues #30 and #31 to follow up with these.