forked from solana-labs/solana
-
Notifications
You must be signed in to change notification settings - Fork 259
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[zk-sdk] Add
pod
modules for sigma and range proofs (#1281)
* add sigma `pod` module * clean up pod sigma proofs * add rangeproof `pod` module * clean up pod range proofs * update old constant names * update outdated comments * Update zk-sdk/src/sigma_proofs/pod.rs Co-authored-by: Jon C <[email protected]> --------- Co-authored-by: Jon C <[email protected]>
- Loading branch information
1 parent
c0e9149
commit d54e808
Showing
4 changed files
with
449 additions
and
2 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
//! Plain Old Data types for range proofs. | ||
#[cfg(not(target_os = "solana"))] | ||
use crate::{ | ||
range_proof::{errors::RangeProofVerificationError, RangeProof}, | ||
UNIT_LEN, | ||
}; | ||
use { | ||
crate::range_proof::*, | ||
bytemuck::{Pod, Zeroable}, | ||
}; | ||
|
||
/// The `RangeProof` type as a `Pod` restricted to proofs on 64-bit numbers. | ||
#[derive(Clone, Copy)] | ||
#[repr(transparent)] | ||
pub struct PodRangeProofU64(pub(crate) [u8; RANGE_PROOF_U64_LEN]); | ||
|
||
#[cfg(not(target_os = "solana"))] | ||
impl TryFrom<RangeProof> for PodRangeProofU64 { | ||
type Error = RangeProofVerificationError; | ||
|
||
fn try_from(decoded_proof: RangeProof) -> Result<Self, Self::Error> { | ||
if decoded_proof.ipp_proof.serialized_size() != INNER_PRODUCT_PROOF_U64_LEN { | ||
return Err(RangeProofVerificationError::Deserialization); | ||
} | ||
|
||
let mut buf = [0_u8; RANGE_PROOF_U64_LEN]; | ||
copy_range_proof_modulo_inner_product_proof(&decoded_proof, &mut buf); | ||
buf[RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN..RANGE_PROOF_U64_LEN] | ||
.copy_from_slice(&decoded_proof.ipp_proof.to_bytes()); | ||
Ok(PodRangeProofU64(buf)) | ||
} | ||
} | ||
|
||
#[cfg(not(target_os = "solana"))] | ||
impl TryFrom<PodRangeProofU64> for RangeProof { | ||
type Error = RangeProofVerificationError; | ||
|
||
fn try_from(pod_proof: PodRangeProofU64) -> Result<Self, Self::Error> { | ||
Self::from_bytes(&pod_proof.0) | ||
} | ||
} | ||
|
||
/// The `RangeProof` type as a `Pod` restricted to proofs on 128-bit numbers. | ||
#[derive(Clone, Copy)] | ||
#[repr(transparent)] | ||
pub struct PodRangeProofU128(pub(crate) [u8; RANGE_PROOF_U128_LEN]); | ||
|
||
#[cfg(not(target_os = "solana"))] | ||
impl TryFrom<RangeProof> for PodRangeProofU128 { | ||
type Error = RangeProofVerificationError; | ||
|
||
fn try_from(decoded_proof: RangeProof) -> Result<Self, Self::Error> { | ||
if decoded_proof.ipp_proof.serialized_size() != INNER_PRODUCT_PROOF_U128_LEN { | ||
return Err(RangeProofVerificationError::Deserialization); | ||
} | ||
|
||
let mut buf = [0_u8; RANGE_PROOF_U128_LEN]; | ||
copy_range_proof_modulo_inner_product_proof(&decoded_proof, &mut buf); | ||
buf[RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN..RANGE_PROOF_U128_LEN] | ||
.copy_from_slice(&decoded_proof.ipp_proof.to_bytes()); | ||
Ok(PodRangeProofU128(buf)) | ||
} | ||
} | ||
|
||
#[cfg(not(target_os = "solana"))] | ||
impl TryFrom<PodRangeProofU128> for RangeProof { | ||
type Error = RangeProofVerificationError; | ||
|
||
fn try_from(pod_proof: PodRangeProofU128) -> Result<Self, Self::Error> { | ||
Self::from_bytes(&pod_proof.0) | ||
} | ||
} | ||
|
||
/// The `RangeProof` type as a `Pod` restricted to proofs on 256-bit numbers. | ||
#[derive(Clone, Copy)] | ||
#[repr(transparent)] | ||
pub struct PodRangeProofU256(pub(crate) [u8; RANGE_PROOF_U256_LEN]); | ||
|
||
#[cfg(not(target_os = "solana"))] | ||
impl TryFrom<RangeProof> for PodRangeProofU256 { | ||
type Error = RangeProofVerificationError; | ||
|
||
fn try_from(decoded_proof: RangeProof) -> Result<Self, Self::Error> { | ||
if decoded_proof.ipp_proof.serialized_size() != INNER_PRODUCT_PROOF_U256_LEN { | ||
return Err(RangeProofVerificationError::Deserialization); | ||
} | ||
|
||
let mut buf = [0_u8; RANGE_PROOF_U256_LEN]; | ||
copy_range_proof_modulo_inner_product_proof(&decoded_proof, &mut buf); | ||
buf[RANGE_PROOF_MODULO_INNER_PRODUCT_PROOF_LEN..RANGE_PROOF_U256_LEN] | ||
.copy_from_slice(&decoded_proof.ipp_proof.to_bytes()); | ||
Ok(PodRangeProofU256(buf)) | ||
} | ||
} | ||
|
||
#[cfg(not(target_os = "solana"))] | ||
impl TryFrom<PodRangeProofU256> for RangeProof { | ||
type Error = RangeProofVerificationError; | ||
|
||
fn try_from(pod_proof: PodRangeProofU256) -> Result<Self, Self::Error> { | ||
Self::from_bytes(&pod_proof.0) | ||
} | ||
} | ||
|
||
#[cfg(not(target_os = "solana"))] | ||
fn copy_range_proof_modulo_inner_product_proof(proof: &RangeProof, buf: &mut [u8]) { | ||
let mut chunks = buf.chunks_mut(UNIT_LEN); | ||
chunks.next().unwrap().copy_from_slice(proof.A.as_bytes()); | ||
chunks.next().unwrap().copy_from_slice(proof.S.as_bytes()); | ||
chunks.next().unwrap().copy_from_slice(proof.T_1.as_bytes()); | ||
chunks.next().unwrap().copy_from_slice(proof.T_2.as_bytes()); | ||
chunks.next().unwrap().copy_from_slice(proof.t_x.as_bytes()); | ||
chunks | ||
.next() | ||
.unwrap() | ||
.copy_from_slice(proof.t_x_blinding.as_bytes()); | ||
chunks | ||
.next() | ||
.unwrap() | ||
.copy_from_slice(proof.e_blinding.as_bytes()); | ||
} | ||
|
||
// The range proof pod types are wrappers for byte arrays, which are both `Pod` and `Zeroable`. However, | ||
// the marker traits `bytemuck::Pod` and `bytemuck::Zeroable` can only be derived for power-of-two | ||
// length byte arrays. Directly implement these traits for the range proof pod types. | ||
unsafe impl Zeroable for PodRangeProofU64 {} | ||
unsafe impl Pod for PodRangeProofU64 {} | ||
|
||
unsafe impl Zeroable for PodRangeProofU128 {} | ||
unsafe impl Pod for PodRangeProofU128 {} | ||
|
||
unsafe impl Zeroable for PodRangeProofU256 {} | ||
unsafe impl Pod for PodRangeProofU256 {} |
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
Oops, something went wrong.