-
Notifications
You must be signed in to change notification settings - Fork 302
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
crypto: create new crate, scratch work
Adds asset identifiers and value commitment generator computation. This commit changes the workspace to use a Penumbra fork of some of the arkworks crates. The current change is in the Display impl for Fp* instances. The fork's `ours` branch is based off of `v0.3.0`, in order to not pick up any unreleased breaking changes.
- Loading branch information
1 parent
9f6ac72
commit e133018
Showing
7 changed files
with
149 additions
and
3 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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,16 @@ | ||
[package] | ||
name = "penumbra-crypto" | ||
version = "0.1.0" | ||
edition = "2018" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
decaf377 = { git = "https://github.com/penumbra-zone/decaf377" } | ||
poseidon377 = { git = "https://github.com/penumbra-zone/poseidon377" } | ||
hex = "0.4" | ||
blake2b_simd = "0.5" | ||
ark-ff = "0.3" | ||
once_cell = "1.8" | ||
# only needed because ark-ff doesn't display correctly | ||
num-bigint = "0.4" |
This file contains 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,85 @@ | ||
//! Asset types and identifiers. | ||
use ark_ff::fields::PrimeField; | ||
use once_cell::sync::Lazy; | ||
|
||
use crate::Fq; | ||
|
||
/// An identifier for an IBC asset type. | ||
/// | ||
/// This is similar to, but different from, the design in [ADR001]. As in | ||
/// ADR001, a denomination trace is hashed to a fixed-size identifier, but | ||
/// unlike ADR001, we hash to a field element rather than a byte string. | ||
/// | ||
/// A denomination trace looks like | ||
/// | ||
/// - `denom` (native chain A asset) | ||
/// - `transfer/channelToA/denom` (chain B representation of chain A asset) | ||
/// - `transfer/channelToB/transfer/channelToA/denom` (chain C representation of chain B representation of chain A asset) | ||
/// | ||
/// ADR001 defines the IBC asset ID as the SHA-256 hash of the denomination | ||
/// trace. Instead, Penumbra hashes to a field element, so that asset IDs can | ||
/// be more easily used inside of a circuit. | ||
/// | ||
/// [ADR001]: | ||
/// https://github.com/cosmos/ibc-go/blob/main/docs/architecture/adr-001-coin-source-tracing.md | ||
#[derive(Copy, Clone, PartialEq, Eq)] | ||
pub struct Id(pub Fq); | ||
|
||
impl std::fmt::Debug for Id { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
f.write_fmt(format_args!("asset::Id({})", self.0.to_string())) | ||
} | ||
} | ||
|
||
// XXX define a DenomTrace structure ? | ||
|
||
impl From<&[u8]> for Id { | ||
fn from(slice: &[u8]) -> Id { | ||
// Convert an asset name to an asset ID by hashing to a scalar | ||
Id(Fq::from_le_bytes_mod_order( | ||
// XXX choice of hash function? | ||
blake2b_simd::Params::default() | ||
.personal(b"penumbra.asset") | ||
.hash(slice) | ||
.as_bytes(), | ||
)) | ||
} | ||
} | ||
|
||
/// The domain separator used to hash asset ids to value generators. | ||
static VALUE_GENERATOR_DOMAIN_SEP: Lazy<Fq> = Lazy::new(|| { | ||
Fq::from_le_bytes_mod_order(blake2b_simd::blake2b(b"penumbra.value.generator").as_bytes()) | ||
}); | ||
|
||
impl Id { | ||
/// Compute the value commitment generator for this asset. | ||
pub fn value_generator(&self) -> decaf377::Element { | ||
use crate::poseidon_hash::hash_1; | ||
let hash = hash_1(&VALUE_GENERATOR_DOMAIN_SEP, self.0); | ||
decaf377::Element::map_to_group_cdh(&hash) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn make_up_some_fake_asset_ids() { | ||
// marked for future deletion | ||
// not really a test, just a way to exercise the code | ||
|
||
let pen_trace = b"pen"; | ||
let atom_trace = b"HubPort/HubChannel/atom"; | ||
|
||
let pen_id = Id::from(&pen_trace[..]); | ||
let atom_id = Id::from(&atom_trace[..]); | ||
|
||
dbg!(pen_id); | ||
dbg!(atom_id); | ||
|
||
dbg!(pen_id.value_generator()); | ||
dbg!(atom_id.value_generator()); | ||
} | ||
} |
This file contains 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,5 @@ | ||
pub use decaf377::Fq; | ||
|
||
pub mod asset; | ||
|
||
mod poseidon_hash; |
This file contains 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,37 @@ | ||
// XXX move into poseidon377 crate? | ||
|
||
use crate::Fq; | ||
|
||
use poseidon377::ark_sponge::{ | ||
poseidon::PoseidonSponge, CryptographicSponge, FieldBasedCryptographicSponge, | ||
}; | ||
|
||
pub fn hash_1(domain_separator: &Fq, value: Fq) -> Fq { | ||
// we want to set the capacity to domain_separator and the rate to value, | ||
// then run the sponge and extract the rate. it's a bit hard to do this | ||
// using the ark-sponge api, which is trying to do a higher-level duplex | ||
// construction and doesn't allow access to the underlying sponge | ||
|
||
let mut sponge = PoseidonSponge::new(&poseidon377::params::rate_1()); | ||
|
||
// arkworks sponge api doesn't let us call permute | ||
// | ||
// best we can do now is to look in the source to see how the rate and | ||
// capacity are arranged and try to plumb the functionality we want through | ||
// the higher-level API | ||
// | ||
// arkworks uses (rate || capacity) instead of (capacity || rate) | ||
// | ||
// this also gives incompatible outputs, but let's deal with that later | ||
|
||
// set the capacity | ||
assert_eq!(sponge.state.len(), 2); | ||
sponge.state[1] = *domain_separator; | ||
|
||
// now use absorb to set the rate (hopefully) | ||
sponge.absorb(&value); | ||
// and squeeze an element | ||
let out_vec = sponge.squeeze_native_field_elements(1); | ||
|
||
out_vec.into_iter().next().unwrap() | ||
} |
This file contains 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