forked from zcash/orchard
-
Notifications
You must be signed in to change notification settings - Fork 0
issuer keys implementation #5
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
Merged
Merged
Changes from 3 commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
0d7ecad
Circleci project setup (#1)
PaulLaux f68cfba
issuer keys tests OK
daniben31 8fd4193
fixes ci test
daniben31 fa66f91
fix CI intra-doc test
daniben31 7ff55bf
issuer keys tests OK
daniben31 8320d70
fixes ci test
daniben31 05978c7
fix CI intra-doc test
daniben31 66acad3
merge rebase of zsa1 branch
daniben31 0bb3298
remove comments and TODOs
daniben31 b0d6034
refactor structural test of verification keys
daniben31 8125267
improved syntax
PaulLaux 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 |
|---|---|---|
|
|
@@ -203,6 +203,108 @@ impl SpendValidatingKey { | |
| } | ||
| } | ||
|
|
||
| /// An issuer authorizing key, used to create issuer authorization signatures. | ||
| /// This type enforces that the corresponding public point (ik^ℙ) has ỹ = 0. | ||
| /// | ||
| /// $\mathsf{isk}$ as defined in | ||
| /// [Zcash Protocol Spec § 4.2.3: Orchard Key Components][orchardkeycomponents]. | ||
| /// | ||
| /// [orchardkeycomponents]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents | ||
| #[derive(Clone, Debug)] | ||
| pub struct IssuerAuthorizingKey(redpallas::SigningKey<SpendAuth>); | ||
|
|
||
| impl IssuerAuthorizingKey { | ||
| /// Derives ask from sk. Internal use only, does not enforce all constraints. | ||
| fn derive_inner(sk: &SpendingKey) -> pallas::Scalar { | ||
| to_scalar(PrfExpand::ZsaIsk.expand(&sk.0)) | ||
| } | ||
|
|
||
| /// Randomizes this spend authorizing key with the given `randomizer`. | ||
| /// TODO: not sure we need a randomizer (remove?) | ||
| /// The resulting key can be used to actually sign a spend. | ||
| pub fn randomize(&self, randomizer: &pallas::Scalar) -> redpallas::SigningKey<SpendAuth> { | ||
| self.0.randomize(randomizer) | ||
| } | ||
| } | ||
|
|
||
| impl From<&SpendingKey> for IssuerAuthorizingKey { | ||
| fn from(sk: &SpendingKey) -> Self { | ||
| let isk = Self::derive_inner(sk); | ||
| // IssuerSigningKey cannot be constructed such that this assertion would fail. | ||
| assert!(!bool::from(isk.is_zero())); | ||
| // TODO: Add TryFrom<S::Scalar> for IssuerAuthorizingKey. | ||
|
PaulLaux marked this conversation as resolved.
Outdated
|
||
| let ret = IssuerAuthorizingKey(isk.to_repr().try_into().unwrap()); | ||
| // If the last bit of repr_P(ik) is 1, negate isk. | ||
| if (<[u8; 32]>::from(IssuerValidatingKey::from(&ret).0)[31] >> 7) == 1 { | ||
| IssuerAuthorizingKey((-isk).to_repr().try_into().unwrap()) | ||
| } else { | ||
| ret | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// A key used to validate issuer authorization signatures. | ||
| /// | ||
| /// Defined in [Zcash Protocol Spec § 4.2.3: Orchard Key Components][orchardkeycomponents]. | ||
| /// Note that this is $\mathsf{ik}^\mathbb{P}$, which by construction is equivalent to | ||
| /// $\mathsf{ik}$ but stored here as a RedPallas verification key. | ||
| /// | ||
| /// [orchardkeycomponents]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents | ||
| #[derive(Debug, Clone, PartialOrd, Ord)] | ||
| pub struct IssuerValidatingKey(redpallas::VerificationKey<SpendAuth>); | ||
| // Discuss <SpendAuth> | ||
|
PaulLaux marked this conversation as resolved.
Outdated
|
||
| impl From<&IssuerAuthorizingKey> for IssuerValidatingKey { | ||
| fn from(isk: &IssuerAuthorizingKey) -> Self { | ||
| IssuerValidatingKey((&isk.0).into()) | ||
| } | ||
| } | ||
|
|
||
| impl From<&IssuerValidatingKey> for pallas::Point { | ||
| fn from(issuer_validating_key: &IssuerValidatingKey) -> pallas::Point { | ||
| pallas::Point::from_bytes(&(&issuer_validating_key.0).into()).unwrap() | ||
| } | ||
| } | ||
|
|
||
| impl PartialEq for IssuerValidatingKey { | ||
| fn eq(&self, other: &Self) -> bool { | ||
| <[u8; 32]>::from(&self.0).eq(&<[u8; 32]>::from(&other.0)) | ||
| } | ||
| } | ||
|
|
||
| impl Eq for IssuerValidatingKey {} | ||
|
|
||
| impl IssuerValidatingKey { | ||
| /// Randomizes this spend validating key with the given `randomizer`. | ||
| pub fn randomize(&self, randomizer: &pallas::Scalar) -> redpallas::VerificationKey<SpendAuth> { | ||
| self.0.randomize(randomizer) | ||
| } | ||
|
|
||
| /// Converts this spend validating key to its serialized form, | ||
| /// I2LEOSP_256(ak). | ||
|
PaulLaux marked this conversation as resolved.
Outdated
|
||
| pub(crate) fn to_bytes(&self) -> [u8; 32] { | ||
| // This is correct because the wrapped point must have ỹ = 0, and | ||
| // so the point repr is the same as I2LEOSP of its x-coordinate. | ||
| <[u8; 32]>::from(&self.0) | ||
| } | ||
|
|
||
| pub(crate) fn from_bytes(bytes: &[u8]) -> Option<Self> { | ||
| <[u8; 32]>::try_from(bytes) | ||
| .ok() | ||
| .and_then(|b| { | ||
| // Structural validity checks for ik_P: | ||
| // - The point must not be the identity | ||
| // (which for Pallas is canonically encoded as all-zeroes). | ||
| // - The sign of the y-coordinate must be positive. | ||
| if b != [0; 32] && b[31] & 0x80 == 0 { | ||
| <redpallas::VerificationKey<SpendAuth>>::try_from(b).ok() | ||
| } else { | ||
| None | ||
| } | ||
|
Collaborator
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. This code is critical, let's extract this into a function to prevent duplication with fn check_structural_validity(verification_key_bytes: &[u8; 32]) -> Option<&[u8; 32]> {
} |
||
| }) | ||
| .map(IssuerValidatingKey) | ||
| } | ||
| } | ||
|
|
||
| /// A key used to derive [`Nullifier`]s from [`Note`]s. | ||
| /// | ||
| /// $\mathsf{nk}$ as defined in [Zcash Protocol Spec § 4.2.3: Orchard Key Components][orchardkeycomponents]. | ||
|
|
@@ -1021,9 +1123,15 @@ mod tests { | |
| let ask: SpendAuthorizingKey = (&sk).into(); | ||
| assert_eq!(<[u8; 32]>::from(&ask.0), tv.ask); | ||
|
|
||
| let isk: IssuerAuthorizingKey = (&sk).into(); | ||
| assert_eq!(<[u8; 32]>::from(&isk.0), tv.isk); | ||
|
|
||
| let ak: SpendValidatingKey = (&ask).into(); | ||
| assert_eq!(<[u8; 32]>::from(ak.0), tv.ak); | ||
|
|
||
| let ik: IssuerValidatingKey = (&isk).into(); | ||
| assert_eq!(<[u8; 32]>::from(ik.0), tv.ik); | ||
|
|
||
| let nk: NullifierDerivingKey = (&sk).into(); | ||
| assert_eq!(nk.0.to_repr(), tv.nk); | ||
|
|
||
|
|
||
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
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
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
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.