-
Notifications
You must be signed in to change notification settings - Fork 0
Code review #2
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
Open
jspada
wants to merge
57
commits into
code-review
Choose a base branch
from
main
base: code-review
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Code review #2
Changes from 23 commits
Commits
Show all changes
57 commits
Select commit
Hold shift + click to select a range
ef326e9
Initial work on mina signer library
jspada a4bde88
Removed blake2 hasher from signer context
jspada 891fa52
Refactored Context into Schnorr
jspada bcb57c1
Some cleanup
jspada 0f2e302
Work in progress on random oracle input
jspada 62fac46
Implemented functionality in order to unit test
jspada c469f56
Added get_address unit tests
jspada 7de6229
Clean up some things
jspada ab5f933
Work on random oracle input
jspada 2bd0a70
Progess with random oracle input
jspada b2b2f41
Completed random oracle to_bytes
jspada 6561369
Completed random oracle input implementation
jspada 73d81e1
Finished up Schnorr signing algorithm
jspada 1868f66
Added some positive test cases
jspada bb8ceba
Started on mina sign and verify unit testing
jspada 02584d2
Implemented PubKey::from_address()/b58 and memo_str()
jspada ff48083
Work on first transaction signing unit test
jspada 8042c3e
Work in progress on signing unit tests
jspada e79812f
Work in progress on transaction signing
jspada 498f144
Completed work on signing and basic signing unit tests
jspada 5cde7e0
Signer improvements
jspada 2cba726
Implemented Mina signature verification
jspada 9c84cab
Updated gitignore
jspada 68b1d93
Ran cargo fmt
jspada 64b3b91
Improvements suggested by clippy
jspada 8057454
Remove spaces between use
jspada 405b74f
Removed unnecessary test gating
jspada bec13a1
Minimize imports, don't use domain::*
jspada 9f1c5c8
Be more verbose about test name
jspada 341cd72
Updated to latest proof-systems
jspada 96c8dee
Fixed formatting
jspada 78a2142
Code review items
jspada 951bcba
Code review update
jspada 8247678
Created documentation
jspada 269aadf
Documentation updates
jspada f7b2990
Finished documentation
jspada 5bb8888
Added an example to documentation
jspada f3f4e62
Added zero signature unit test
jspada 456cf3e
Add a comment about converting field
jspada 638743d
Switch away from bitvec's as_raw_slice()
jspada 6be248d
Switched some function args from Vec to slice
jspada 9f1c6e9
Improved names on Keypair members and updated mutability on a couple …
jspada ab987ec
Minor updates
jspada 89a7b56
Renamed some things for clarity and to remove dependence on specific …
jspada c16fad5
Documented some security decisions and internal functions
jspada f60c6da
Added scalar from bytes helper interface
jspada f56606b
Switch some of verification to projective form
jspada 1e2db04
Move Mina-specific hex serialization to Keypair/SecKey/Signature layer
jspada e6f2f80
Refactored FieldHelpers into single generic trait for all field eleme…
jspada 83d55f2
Split Input trait into Hashable and Signable
jspada c4a4dd7
Added wrapper structs for SecKey and PubKey
jspada 8574c72
Moved SecKey to separate module
jspada 085e740
Updated Keypair::rand to take Rng argument
jspada e10c662
Refactor unit test macros into single macro
jspada 3a2913e
Updated documentation
jspada f9e8c9f
Removed submodule proof-systems
jspada 729a879
Updated dependencies
jspada File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,3 +8,5 @@ Cargo.lock | |
|
|
||
| # These are backup files generated by rustfmt | ||
| **/*.rs.bk | ||
|
|
||
| .vscode | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| [submodule "proof-systems"] | ||
| path = proof-systems | ||
| url = [email protected]:o1-labs/proof-systems.git |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| [package] | ||
| name = "signer" | ||
| version = "0.1.0" | ||
| authors = ["Joseph Spadavecchia <[email protected]>"] | ||
| edition = "2018" | ||
|
|
||
| [lib] | ||
| path = "src/lib.rs" | ||
|
|
||
| [dependencies] | ||
| oracle = { path = "./proof-systems/oracle" } | ||
| algebra = { path = "./proof-systems/zexe/algebra", features = [ "pasta" ] } | ||
| mina-curves = { path = "./proof-systems/curves" } | ||
| commitment_dlog = { path = "./proof-systems/dlog/commitment" } | ||
| rand_core = { version = "0.5" } | ||
| array-init = { version = "0.1.1" } | ||
| blake2 = { version = "0.9.1" } | ||
| hex = { version = "0.4" } | ||
| bitvec = { version = "0.22.3" } | ||
| sha2 = { version = "0.9.6" } | ||
| bs58 = { version = "0.4.0" } | ||
| byteordered = { version = "0.6.0" } | ||
| byteorder = { version = "1.4.3" } | ||
Submodule proof-systems
added at
6b93db
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| pub use algebra::AffineCurve; | ||
| pub use algebra::Field; | ||
jspada marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| use mina_curves::pasta::pallas as Pallas; | ||
| pub use Pallas::Affine as PallasPoint; | ||
jspada marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| pub type PallasField = <PallasPoint as AffineCurve>::BaseField; | ||
jspada marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| pub type PallasScalar = <PallasPoint as AffineCurve>::ScalarField; | ||
|
|
||
| use algebra::{ | ||
| CanonicalSerialize as _, | ||
| CanonicalDeserialize as _, | ||
| PrimeField, // for into_repr() | ||
| }; | ||
|
|
||
| pub trait FieldHelpers { | ||
| fn from_bytes(bytes: Vec<u8>) -> PallasField; | ||
jspada marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| fn from_hex(hex: &str) -> Result<PallasField, &str>; | ||
| fn to_bytes(self) -> Vec<u8>; | ||
| fn to_string(self) -> String; | ||
jspada marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| impl FieldHelpers for PallasField { | ||
| fn from_hex(hex: &str) -> Result<PallasField, &str> { | ||
| if hex.len() != 64 { | ||
jspada marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return Err("Invalid field hex length"); | ||
| } | ||
|
|
||
| let bytes: Vec<u8> = hex::decode(hex).or_else( | ||
| |_| Err("Failed to decode field hex") | ||
| )?; | ||
|
|
||
| return PallasField::deserialize(&mut &bytes[..]).or_else( | ||
| |_| Err("Failed to deserialize field bytes") | ||
| ); | ||
| } | ||
|
|
||
| fn from_bytes(bytes: Vec<u8>) -> PallasField { | ||
jspada marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return PallasField::deserialize(&mut &bytes[..]).expect("failed to deserialize field"); | ||
| } | ||
|
|
||
| fn to_bytes(self) -> Vec<u8> { | ||
| let mut bytes: Vec<u8> = vec![]; | ||
| self.into_repr() | ||
| .serialize(&mut bytes) | ||
| .expect("Failed to serialize field"); // TODO: OK error handling? | ||
jspada marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return bytes; | ||
| } | ||
|
|
||
| fn to_string(self) -> String { | ||
| let mut bytes = self.to_bytes(); | ||
| bytes.reverse(); | ||
jspada marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return hex::encode(bytes); | ||
| } | ||
| } | ||
|
|
||
| // TODO: Combine into single Helpers trait (why did rust require two?!) | ||
jspada marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| pub trait ScalarHelpers { | ||
| fn from_hex(hex: &str) -> Result<PallasScalar, &str>; | ||
| fn to_bytes(self) -> Vec<u8>; | ||
| fn to_string(self) -> String; | ||
| } | ||
|
|
||
| impl ScalarHelpers for PallasScalar { | ||
| fn from_hex(hex: &str) -> Result<PallasScalar, &str> { | ||
| if hex.len() != 64 { | ||
| return Err("Invalid scalar hex length"); | ||
| } | ||
|
|
||
| let mut bytes: Vec<u8> = hex::decode(hex).or_else( | ||
| |_| Err("Failed to decode scalar hex") | ||
| )?; | ||
| bytes.reverse(); // mina scalars hex format is in big-endian order | ||
|
|
||
| return PallasScalar::deserialize(&mut &bytes[..]).or_else( | ||
| |_| Err("Failed to deserialize scalar bytes") | ||
| ); | ||
| } | ||
|
|
||
| fn to_bytes(self) -> Vec<u8> { | ||
| let mut bytes: Vec<u8> = vec![]; | ||
| self.into_repr() | ||
| .serialize(&mut bytes) | ||
| .expect("failed to serialize scalar"); // TODO: OK error handling? | ||
| return bytes; | ||
| } | ||
|
|
||
| fn to_string(self) -> String { | ||
| let mut bytes = self.to_bytes(); | ||
| bytes.reverse(); | ||
| return hex::encode(bytes); | ||
| } | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
|
|
||
| #[test] | ||
| fn field_from_hex() { | ||
| assert_eq!(PallasField::from_hex(""), Err("Invalid field hex length")); | ||
| assert_eq!(PallasField::from_hex("1428fadcf0c02396e620f14f176fddb5d769b7de2027469d027a80142ef8f07"), Err("Invalid field hex length")); | ||
| assert_eq!(PallasField::from_hex("0f5314f176fddb5d769b7de2027469d027ad428fadcf0c02396e6280142efb7d8"), Err("Invalid field hex length")); | ||
| assert_eq!(PallasField::from_hex("g64244176fddb5d769b7de2027469d027ad428fadcf0c02396e6280142efb7d8"), Err("Failed to decode field hex")); | ||
| assert_eq!(PallasField::from_hex("0cdaf334e9632268a5aa959c2781fb32bf45565fe244ae42c849d3fdc7c644fd"), Err("Failed to deserialize field bytes")); | ||
|
|
||
| assert_eq!(PallasField::from_hex("2eaedae42a7461d5952d27b97ecad068b698ebb94e8a0e4c45388bb613de7e08").is_ok(), true); | ||
| } | ||
|
|
||
| #[test] | ||
| fn scalar_from_hex() { | ||
| assert_eq!(PallasScalar::from_hex(""), Err("Invalid scalar hex length")); | ||
| assert_eq!(PallasScalar::from_hex("1428fadcf0c02396e620f14f176fddb5d769b7de2027469d027a80142ef8f07"), Err("Invalid scalar hex length")); | ||
| assert_eq!(PallasScalar::from_hex("0f5314f176fddb5d769b7de2027469d027ad428fadcf0c02396e6280142efb7d8"), Err("Invalid scalar hex length")); | ||
| assert_eq!(PallasScalar::from_hex("g64244176fddb5d769b7de2027469d027ad428fadcf0c02396e6280142efb7d8"), Err("Failed to decode scalar hex")); | ||
| assert_eq!(PallasScalar::from_hex("dd4244176fddb5d769b7de2027469d027ad428fadcc0c02396e6280142efb718"), Err("Failed to deserialize scalar bytes")); | ||
|
|
||
| assert_eq!(PallasScalar::from_hex("238344cc01fd5d8cfc7c69cc4a7497bcdb3cb9810d0f8b571615dc3da2433cc2").is_ok(), true); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| use algebra::{ProjectiveCurve, UniformRand}; | ||
|
|
||
| use crate::domain::*; | ||
|
|
||
| use crate::pubkey::*; | ||
jspada marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| pub type SecKey = PallasScalar; | ||
jspada marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| #[derive(Debug, Copy, Clone, PartialEq)] | ||
| pub struct Keypair { | ||
| pub sec_key: SecKey, | ||
| pub pub_key: PubKey, | ||
jspada marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| impl Keypair { | ||
| pub fn rand() -> Self { | ||
| let sec_key: PallasScalar = PallasScalar::rand(&mut rand_core::OsRng); | ||
| let pub_key: PallasPoint = PallasPoint::prime_subgroup_generator().mul(sec_key).into_affine(); | ||
| return Keypair { sec_key: sec_key, pub_key: pub_key}; | ||
| } | ||
|
|
||
| pub fn from_hex(sec_key_hex: &str) -> Result<Self, &'static str> { | ||
| let sec_key = PallasScalar::from_hex(sec_key_hex).or_else( | ||
| |_| Err("Invalid secret key hex") | ||
| )?; | ||
| let pub_key: PallasPoint = PallasPoint::prime_subgroup_generator().mul(sec_key).into_affine(); | ||
| return Ok(Keypair { sec_key: sec_key, pub_key: pub_key}); | ||
| } | ||
|
|
||
| pub fn address(self) -> String { | ||
| return self.pub_key.to_address(); | ||
| } | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
|
|
||
| #[test] | ||
| fn from_hex() { | ||
| assert_eq!(Keypair::from_hex(""), Err("Invalid secret key hex")); | ||
| assert_eq!(Keypair::from_hex("1428fadcf0c02396e620f14f176fddb5d769b7de2027469d027a80142ef8f07"), Err("Invalid secret key hex")); | ||
| assert_eq!(Keypair::from_hex("0f5314f176fddb5d769b7de2027469d027ad428fadcf0c02396e6280142efb7d8"), Err("Invalid secret key hex")); | ||
| assert_eq!(Keypair::from_hex("g64244176fddb5d769b7de2027469d027ad428fadcf0c02396e6280142efb7d8"), Err("Invalid secret key hex")); | ||
| assert_eq!(Keypair::from_hex("dd4244176fddb5d769b7de2027469d027ad428fadcc0c02396e6280142efb718"), Err("Invalid secret key hex")); | ||
|
|
||
| let kp = Keypair::from_hex("164244176fddb5d769b7de2027469d027ad428fadcc0c02396e6280142efb718").expect( | ||
| "failed to decode keypair secret key"); | ||
|
|
||
| println!("address = {}", kp.pub_key.to_address()); | ||
| } | ||
|
|
||
| #[test] | ||
| fn address() { | ||
jspada marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| macro_rules! assert_get_address_eq { | ||
| ($sec_key_hex:expr, $target_address:expr) => { | ||
| let kp = Keypair::from_hex($sec_key_hex).expect("failed to create keypair"); | ||
| assert_eq!(kp.address(), $target_address); | ||
| }; | ||
| } | ||
|
|
||
| assert_get_address_eq!("164244176fddb5d769b7de2027469d027ad428fadcc0c02396e6280142efb718", "B62qnzbXmRNo9q32n4SNu2mpB8e7FYYLH8NmaX6oFCBYjjQ8SbD7uzV"); | ||
| assert_get_address_eq!("3ca187a58f09da346844964310c7e0dd948a9105702b716f4d732e042e0c172e", "B62qicipYxyEHu7QjUqS7QvBipTs5CzgkYZZZkPoKVYBu6tnDUcE9Zt"); | ||
| assert_get_address_eq!("336eb4a19b3d8905824b0f2254fb495573be302c17582748bf7e101965aa4774", "B62qrKG4Z8hnzZqp1AL8WsQhQYah3quN1qUj3SyfJA8Lw135qWWg1mi"); | ||
| assert_get_address_eq!("1dee867358d4000f1dafa5978341fb515f89eeddbe450bd57df091f1e63d4444", "B62qoqiAgERjCjXhofXiD7cMLJSKD8hE8ZtMh4jX5MPNgKB4CFxxm1N"); | ||
| assert_get_address_eq!("20f84123a26e58dd32b0ea3c80381f35cd01bc22a20346cc65b0a67ae48532ba", "B62qkiT4kgCawkSEF84ga5kP9QnhmTJEYzcfgGuk6okAJtSBfVcjm1M"); | ||
| assert_get_address_eq!("3414fc16e86e6ac272fda03cf8dcb4d7d47af91b4b726494dab43bf773ce1779", "B62qoG5Yk4iVxpyczUrBNpwtx2xunhL48dydN53A2VjoRwF8NUTbVr4"); | ||
| } | ||
| } | ||
jspada marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| pub mod domain; | ||
| pub mod pubkey; | ||
| pub mod keypair; | ||
| pub mod roinput; | ||
| pub mod signature; | ||
| pub mod schnorr; | ||
|
|
||
| pub use domain::*; | ||
|
|
||
| pub use pubkey::PubKey; | ||
| pub use pubkey::PubKeyHelpers; | ||
| pub use pubkey::CompressedPubKey; | ||
| pub use keypair::Keypair; | ||
| pub use roinput::{ | ||
| Input, | ||
| ROInput, | ||
| }; | ||
| pub use signature::Signature; | ||
| pub use schnorr::Schnorr; | ||
|
|
||
| use oracle::{ | ||
| pasta, | ||
| poseidon::{ | ||
| Sponge, | ||
| ArithmeticSponge, | ||
| SpongeConstants, | ||
| ArithmeticSpongeParams, | ||
| PlonkSpongeConstants, | ||
| }, | ||
| }; | ||
|
|
||
| #[derive(Copy, Clone)] | ||
| #[repr(u8)] | ||
jspada marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| pub enum NetworkId { | ||
| TESTNET = 0x00, | ||
| MAINNET = 0x01, | ||
| } | ||
|
|
||
| impl Into<u8> for NetworkId { | ||
| fn into(self) -> u8 { | ||
| self as u8 | ||
| } | ||
| } | ||
|
|
||
| pub trait Signer { | ||
| fn sign<I: Input>(&mut self, kp: Keypair, input: I) -> Signature; | ||
| fn verify<I: Input>(&mut self, sig: Signature, pub_key: PubKey, input: I) -> bool; | ||
| } | ||
|
|
||
| pub fn create(network_id: NetworkId) -> impl Signer { | ||
| return Schnorr::<PlonkSpongeConstants>::new( | ||
| ArithmeticSponge::<PallasField, PlonkSpongeConstants>::new(pasta::fp::params()), | ||
| network_id, | ||
| ); | ||
| } | ||
|
|
||
| pub fn custom<SC: SpongeConstants>(params: ArithmeticSpongeParams<PallasField>, network_id: NetworkId) -> impl Signer { | ||
| return Schnorr::<SC>::new( | ||
| ArithmeticSponge::<PallasField, SC>::new(params), | ||
| network_id, | ||
| ); | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.