mirror of
https://github.com/logos-co/nomos-node.git
synced 2026-08-27 09:31:10 +00:00
feat(zk): empower the poq (#3259)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
Copilot Autofix powered by AI
parent
c66f86cb51
commit
23eb2a4635
Generated
+26
-26
@@ -105,7 +105,7 @@ version = "1.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -116,7 +116,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"once_cell_polyfill",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1567,7 +1567,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccc2776f0c61eca1ca32528f85548abd1a4be8fb53d1b21c013e4f18da1e7090"
|
||||
dependencies = [
|
||||
"data-encoding",
|
||||
"syn 2.0.118",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1752,7 +1752,7 @@ dependencies = [
|
||||
"libc",
|
||||
"option-ext",
|
||||
"redox_users",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1968,7 +1968,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3070,7 +3070,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4297,8 +4297,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-circuits-build"
|
||||
version = "0.5.3"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.3#127626881faa975aa8e9868422cf6bbb08fcb512"
|
||||
version = "0.5.5"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.5#32f1ac43f331f0eeff3a2a0aec0f153564d03583"
|
||||
dependencies = [
|
||||
"dirs",
|
||||
"fd-lock",
|
||||
@@ -4309,16 +4309,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-circuits-common"
|
||||
version = "0.5.3"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.3#127626881faa975aa8e9868422cf6bbb08fcb512"
|
||||
version = "0.5.5"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.5#32f1ac43f331f0eeff3a2a0aec0f153564d03583"
|
||||
dependencies = [
|
||||
"logos-blockchain-circuits-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-circuits-poc-sys"
|
||||
version = "0.5.3"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.3#127626881faa975aa8e9868422cf6bbb08fcb512"
|
||||
version = "0.5.5"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.5#32f1ac43f331f0eeff3a2a0aec0f153564d03583"
|
||||
dependencies = [
|
||||
"logos-blockchain-circuits-build",
|
||||
"logos-blockchain-circuits-common",
|
||||
@@ -4327,8 +4327,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-circuits-pol-sys"
|
||||
version = "0.5.3"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.3#127626881faa975aa8e9868422cf6bbb08fcb512"
|
||||
version = "0.5.5"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.5#32f1ac43f331f0eeff3a2a0aec0f153564d03583"
|
||||
dependencies = [
|
||||
"logos-blockchain-circuits-build",
|
||||
"logos-blockchain-circuits-common",
|
||||
@@ -4337,8 +4337,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-circuits-poq-sys"
|
||||
version = "0.5.3"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.3#127626881faa975aa8e9868422cf6bbb08fcb512"
|
||||
version = "0.5.5"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.5#32f1ac43f331f0eeff3a2a0aec0f153564d03583"
|
||||
dependencies = [
|
||||
"logos-blockchain-circuits-build",
|
||||
"logos-blockchain-circuits-common",
|
||||
@@ -4354,8 +4354,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-circuits-signature-sys"
|
||||
version = "0.5.3"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.3#127626881faa975aa8e9868422cf6bbb08fcb512"
|
||||
version = "0.5.5"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.5#32f1ac43f331f0eeff3a2a0aec0f153564d03583"
|
||||
dependencies = [
|
||||
"logos-blockchain-circuits-build",
|
||||
"logos-blockchain-circuits-common",
|
||||
@@ -4364,8 +4364,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-circuits-types"
|
||||
version = "0.5.3"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.3#127626881faa975aa8e9868422cf6bbb08fcb512"
|
||||
version = "0.5.5"
|
||||
source = "git+https://github.com/logos-blockchain/logos-blockchain-circuits.git?tag=v0.5.5#32f1ac43f331f0eeff3a2a0aec0f153564d03583"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"libc",
|
||||
@@ -5890,7 +5890,7 @@ version = "0.50.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7457,7 +7457,7 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.12.1",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7967,7 +7967,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8262,7 +8262,7 @@ dependencies = [
|
||||
"getrandom 0.4.3",
|
||||
"once_cell",
|
||||
"rustix 1.1.4",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8294,7 +8294,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874"
|
||||
dependencies = [
|
||||
"rustix 1.1.4",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -9525,7 +9525,7 @@ version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
+5
-5
@@ -164,11 +164,11 @@ lb-zksign = { default-features = false, package = "logo
|
||||
lb-zone-sdk = { default-features = false, package = "logos-blockchain-zone-sdk", path = "./zone-sdk" }
|
||||
# When bumping any lbc-* tag, also update the logos-blockchain-circuits flake input tag in flake.nix
|
||||
# and run `nix flake lock --update-input logos-blockchain-circuits`.
|
||||
lbc-poc-sys = { default-features = false, git = "https://github.com/logos-blockchain/logos-blockchain-circuits.git", package = "logos-blockchain-circuits-poc-sys", tag = "v0.5.3" }
|
||||
lbc-pol-sys = { default-features = false, git = "https://github.com/logos-blockchain/logos-blockchain-circuits.git", package = "logos-blockchain-circuits-pol-sys", tag = "v0.5.3" }
|
||||
lbc-poq-sys = { default-features = false, git = "https://github.com/logos-blockchain/logos-blockchain-circuits.git", package = "logos-blockchain-circuits-poq-sys", tag = "v0.5.3" }
|
||||
lbc-signature-sys = { default-features = false, git = "https://github.com/logos-blockchain/logos-blockchain-circuits.git", package = "logos-blockchain-circuits-signature-sys", tag = "v0.5.3" }
|
||||
lbc-types = { default-features = false, git = "https://github.com/logos-blockchain/logos-blockchain-circuits.git", package = "logos-blockchain-circuits-types", tag = "v0.5.3" }
|
||||
lbc-poc-sys = { default-features = false, git = "https://github.com/logos-blockchain/logos-blockchain-circuits.git", package = "logos-blockchain-circuits-poc-sys", tag = "v0.5.5" }
|
||||
lbc-pol-sys = { default-features = false, git = "https://github.com/logos-blockchain/logos-blockchain-circuits.git", package = "logos-blockchain-circuits-pol-sys", tag = "v0.5.5" }
|
||||
lbc-poq-sys = { default-features = false, git = "https://github.com/logos-blockchain/logos-blockchain-circuits.git", package = "logos-blockchain-circuits-poq-sys", tag = "v0.5.5" }
|
||||
lbc-signature-sys = { default-features = false, git = "https://github.com/logos-blockchain/logos-blockchain-circuits.git", package = "logos-blockchain-circuits-signature-sys", tag = "v0.5.5" }
|
||||
lbc-types = { default-features = false, git = "https://github.com/logos-blockchain/logos-blockchain-circuits.git", package = "logos-blockchain-circuits-types", tag = "v0.5.5" }
|
||||
lbp-error = { default-features = false, package = "logos-blockchain-proofs-error", path = "./zk/proofs/error" }
|
||||
testing-framework-core = { default-features = false, git = "https://github.com/logos-blockchain/logos-blockchain-testing.git", rev = "db880d61155db3a4f32177ef16b0f1e4bf22b1f6" }
|
||||
testing-framework-runner-compose = { default-features = false, git = "https://github.com/logos-blockchain/logos-blockchain-testing.git", rev = "db880d61155db3a4f32177ef16b0f1e4bf22b1f6" }
|
||||
|
||||
@@ -5,7 +5,7 @@ use lb_blend_proofs::{
|
||||
self, ProofOfQuota, VerifiedProofOfQuota,
|
||||
inputs::prove::{
|
||||
PublicInputs,
|
||||
public::{CoreInputs, LeaderInputs},
|
||||
public::{CoreInputs, LeaderInputs, PowInputs},
|
||||
},
|
||||
},
|
||||
selection::{self, ProofOfSelection, VerifiedProofOfSelection, inputs::VerifyInputs},
|
||||
@@ -24,6 +24,7 @@ use crate::encap::ProofsVerifier;
|
||||
pub struct PoQVerificationInputsMinusSigningKey {
|
||||
pub core: CoreInputs,
|
||||
pub leader: LeaderInputs,
|
||||
pub pow: PowInputs,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -44,6 +45,7 @@ impl Default for PoQVerificationInputsMinusSigningKey {
|
||||
lottery_0: Fr::ZERO,
|
||||
lottery_1: Fr::ZERO,
|
||||
},
|
||||
pow: PowInputs::unwired_placeholder(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,7 +79,7 @@ impl ProofsVerifier for RealProofsVerifier {
|
||||
proof: ProofOfQuota,
|
||||
signing_key: &Ed25519PublicKey,
|
||||
) -> Result<VerifiedProofOfQuota, Self::Error> {
|
||||
let PoQVerificationInputsMinusSigningKey { core, leader } = self.current_inputs;
|
||||
let PoQVerificationInputsMinusSigningKey { core, leader, pow } = self.current_inputs;
|
||||
|
||||
// Try with current input, and if it fails, try with the previous one, if any
|
||||
// (i.e., within the epoch transition period).
|
||||
@@ -90,6 +92,7 @@ impl ProofsVerifier for RealProofsVerifier {
|
||||
.verify(&PublicInputs {
|
||||
core,
|
||||
leader,
|
||||
pow,
|
||||
signing_key: *signing_key.as_inner(),
|
||||
})
|
||||
.map_err(Error::ProofOfQuota);
|
||||
|
||||
@@ -6,8 +6,8 @@ use crate::quota::{
|
||||
Ed25519PublicKey,
|
||||
inputs::prove::{
|
||||
PublicInputs,
|
||||
private::{ProofOfCoreQuotaInputs, ProofOfLeadershipQuotaInputs},
|
||||
public::{CoreInputs, LeaderInputs},
|
||||
private::{ProofOfCoreQuotaInputs, ProofOfLeadershipQuotaInputs, ProofOfWorkQuotaInputs},
|
||||
public::{CoreInputs, LeaderInputs, PowInputs},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -28,11 +28,10 @@ pub fn valid_proof_of_core_quota_inputs(
|
||||
signing_key,
|
||||
core: CoreInputs {
|
||||
quota: core_quota,
|
||||
zk_root:
|
||||
"10774149910279330054096178616484626574938100628643657398591620611653283350567"
|
||||
.parse::<BigUint>()
|
||||
.unwrap()
|
||||
.into(),
|
||||
zk_root: "8648439177578503276872559887462337398415999326614652623958174178821393732006"
|
||||
.parse::<BigUint>()
|
||||
.unwrap()
|
||||
.into(),
|
||||
},
|
||||
leader: LeaderInputs {
|
||||
pol_epoch_nonce: BigUint::from(1u64).into(),
|
||||
@@ -41,93 +40,97 @@ pub fn valid_proof_of_core_quota_inputs(
|
||||
lottery_0,
|
||||
lottery_1,
|
||||
},
|
||||
pow: PowInputs {
|
||||
pow_blend_difficulty: BigUint::from(1u64).into(),
|
||||
pow_quota: 1,
|
||||
},
|
||||
};
|
||||
|
||||
let private_inputs = ProofOfCoreQuotaInputs {
|
||||
core_path_and_selectors: [
|
||||
(
|
||||
"13664394408134714148474230123476522725121022841643115538772760906625244311247",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"19991080109804084229148819955447485980685271866236940378355513894509403472825",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"1719423980074249650282196742833822060536614400613876573240720330836944657046",
|
||||
"7495929195953210541208591724669352166258167386402673863836582332959049741998",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"9139059421670197230454683564023894631544291367010097325710917953251896109820",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"5364655248740251237070591917425080374871240308613634110599105641060308262480",
|
||||
"8777307683015870709408351814333112152804794621246499110711643849444602886454",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"4321492523488456904492279703871677986518013774282254436225897785632983582392",
|
||||
"2036778247346771710692375429289939913839125337381038976370669720942761418159",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"2990224148203398705081847530695215902031679797575769158839150593627687374477",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"10115668570671746589151792513284313334215992216493690986604010084064526087897",
|
||||
"5150238042344629386129384874056943525919076545561275756461664527118718260316",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"6861547258030107481535610157091754819359096245516659866713074178195667725661",
|
||||
"4936482837140898160990313117063047116523911033722639295600657041261330950251",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"8937835534203757508211957478554582398600683099364069427807070320868647534222",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"7263098007194293142502159691381240540663513841811088748578355471278661748398",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"19870876389339998317953427375552419155167215853924118334240834433312282250010",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"8986537640578106247026054824010082082887537390181434985471297569735311570527",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"2677828888032047082692090535060454810065355495500936244017540612071241172074",
|
||||
"20952980496079374121937279088975994236259798048934859728621453910938508315429",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"17555659938930335545491158932916791395314469587225130013830235195468776678581",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"9071399479181997918431555676567419518917037685697025275563780306843446304571",
|
||||
"3127567055231452038159138967497074106547716639376277019791213152208715502108",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"6281992864280083991852918191693022891803454129450254484599792207873685708287",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"17218725285443376817865240748479799866804154572691475341349156521930190101705",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"14439152042823579940992841514440450319175689090721997229482427278436880180442",
|
||||
"4156278452715681991545944691699148599903237834447534444828105997249209183668",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"4375092350636859316334567236773062868645005901112681926345752432026107616905",
|
||||
"18179601246737692255359026481063507429449403349479564041630890140769203876921",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"2391466682452790260991116539507901841740149925567473331054306831262572734122",
|
||||
"20437752904871274044354648385284243748143753378271484669957282746297202768728",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"20964128655175295722279612439890819641847965870342369257222152533521036200042",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"8529481264681700999783095712819666338972397694516091342589511693767349600946",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"11390366370077994090069924023908925478862142650386311632070176411828525668517",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"5917548759338686071972714539493044537194763096388397090814246211223906547270",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"20167409213677086350276694709897905285253180362287004012973310966314090006733",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"2263236988262202014904251664760262847563737954962247776121488194923407644186",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"19725021492526941122134445491655907123723766494432771594886452496452660956448",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"5142311427791207713153244085802613121123367252788982353300919738927631606801",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"9162839441909107733910143825064550229009975662836406280871655871464192283628",
|
||||
false,
|
||||
),
|
||||
]
|
||||
.map(|(value, selector)| (value.parse::<BigUint>().unwrap().into(), selector)),
|
||||
core_sk: "6576495977526760241501499963811136028674473098047722736567052812753357178145"
|
||||
core_sk: "12667207762918681737213577433372645554941956657477853383508894204444641435708"
|
||||
.parse::<BigUint>()
|
||||
.unwrap()
|
||||
.into(),
|
||||
@@ -170,6 +173,10 @@ pub fn valid_proof_of_leadership_quota_inputs(
|
||||
zk_root: BigUint::from(1u64).into(),
|
||||
quota: 1,
|
||||
},
|
||||
pow: PowInputs {
|
||||
pow_blend_difficulty: BigUint::from(1u64).into(),
|
||||
pow_quota: 1,
|
||||
},
|
||||
};
|
||||
|
||||
let private_inputs = ProofOfLeadershipQuotaInputs {
|
||||
@@ -320,3 +327,65 @@ pub fn valid_proof_of_leadership_quota_inputs(
|
||||
|
||||
(public_inputs, private_inputs)
|
||||
}
|
||||
|
||||
// Reference values taken from the tests within the `poq` crate.
|
||||
#[must_use]
|
||||
pub fn valid_proof_of_work_quota_inputs(
|
||||
signing_key: Ed25519PublicKey,
|
||||
pow_quota: u64,
|
||||
) -> (PublicInputs, ProofOfWorkQuotaInputs) {
|
||||
let public_inputs = PublicInputs {
|
||||
signing_key,
|
||||
pow: PowInputs {
|
||||
pow_blend_difficulty:
|
||||
"10631870504716456348838861774188160492563879712126054449569633827216160699117"
|
||||
.parse::<BigUint>()
|
||||
.unwrap()
|
||||
.into(),
|
||||
pow_quota,
|
||||
},
|
||||
core: CoreInputs {
|
||||
zk_root: "7196120816867742764244305920813414287385070139349175831448761050095304066684"
|
||||
.parse::<BigUint>()
|
||||
.unwrap()
|
||||
.into(),
|
||||
quota: 10,
|
||||
},
|
||||
leader: LeaderInputs {
|
||||
pol_epoch_nonce:
|
||||
"10612486568558363932403470969435464905237449260307875593547304337083779862075"
|
||||
.parse::<BigUint>()
|
||||
.unwrap()
|
||||
.into(),
|
||||
pol_ledger_aged:
|
||||
"12901234158445930888471913831760642108627105440164948073754288938400615804116"
|
||||
.parse::<BigUint>()
|
||||
.unwrap()
|
||||
.into(),
|
||||
message_quota: 15,
|
||||
lottery_0: "148409079361904587837471709956458430342187235603420891378597419711486680"
|
||||
.parse::<BigUint>()
|
||||
.unwrap()
|
||||
.into(),
|
||||
lottery_1:
|
||||
"21888242871336145414933615591437256729835795974444825699352339602896135814447"
|
||||
.parse::<BigUint>()
|
||||
.unwrap()
|
||||
.into(),
|
||||
},
|
||||
};
|
||||
|
||||
let private_inputs = ProofOfWorkQuotaInputs {
|
||||
pow_sk: "10044758699144566038746293679996441958807939592793641056821682251877616662024"
|
||||
.parse::<BigUint>()
|
||||
.unwrap()
|
||||
.into(),
|
||||
pow_block_hash:
|
||||
"17412116459874055221726429396167151400213699852365025340176158516975240665302"
|
||||
.parse::<BigUint>()
|
||||
.unwrap()
|
||||
.into(),
|
||||
};
|
||||
|
||||
(public_inputs, private_inputs)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
use lb_groth16::fr_from_bytes;
|
||||
use lb_poq::{
|
||||
PoQBlendInputsData, PoQChainInputsData, PoQCommonInputsData, PoQInputsFromDataError,
|
||||
PoQWalletInputsData, PoQWitnessInputs,
|
||||
PoQPowInputsData, PoQWalletInputsData, PoQWitnessInputs,
|
||||
};
|
||||
|
||||
use crate::quota::inputs::{
|
||||
prove::private::{ProofOfCoreQuotaInputs, ProofOfLeadershipQuotaInputs, ProofType},
|
||||
prove::private::{
|
||||
ProofOfCoreQuotaInputs, ProofOfLeadershipQuotaInputs, ProofOfWorkQuotaInputs, ProofType,
|
||||
},
|
||||
split_ephemeral_signing_key,
|
||||
};
|
||||
|
||||
@@ -36,6 +38,7 @@ impl TryFrom<Inputs> for PoQWitnessInputs {
|
||||
core_quota: value.public.core.quota,
|
||||
index: value.private.key_index,
|
||||
leader_quota: value.public.leader.message_quota,
|
||||
pow_quota: value.public.pow.pow_quota,
|
||||
message_key: (
|
||||
fr_from_bytes(&signing_key_first_half[..]).expect(
|
||||
"First half of signing public key does not represent a valid `Fr` point.",
|
||||
@@ -45,6 +48,7 @@ impl TryFrom<Inputs> for PoQWitnessInputs {
|
||||
),
|
||||
),
|
||||
selector: value.private.selector,
|
||||
pow_difficulty: value.public.pow.pow_blend_difficulty,
|
||||
};
|
||||
witness_input_for_proof_type(
|
||||
chain_input_data,
|
||||
@@ -91,7 +95,7 @@ fn witness_input_for_proof_type(
|
||||
note_value,
|
||||
output_number,
|
||||
slot,
|
||||
secret_key,
|
||||
pol_secret_key: secret_key,
|
||||
transaction_hash,
|
||||
};
|
||||
PoQWitnessInputs::from_leader_data(
|
||||
@@ -100,5 +104,17 @@ fn witness_input_for_proof_type(
|
||||
wallet_input_data,
|
||||
)
|
||||
}
|
||||
ProofType::PowQuota(pow_quota_private_inputs) => {
|
||||
let ProofOfWorkQuotaInputs {
|
||||
pow_sk,
|
||||
pow_block_hash,
|
||||
} = *pow_quota_private_inputs;
|
||||
|
||||
let pow_input_data = PoQPowInputsData {
|
||||
pow_secret_key: pow_sk,
|
||||
block_hash: pow_block_hash,
|
||||
};
|
||||
PoQWitnessInputs::from_pow_data(chain_input_data, common_input_data, pow_input_data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use core::fmt::{self, Debug, Formatter};
|
||||
|
||||
use lb_poq::AgedNotePathAndSelectors;
|
||||
use lb_poq::{AgedNotePathAndSelectors, PoQSelector};
|
||||
use zeroize::ZeroizeOnDrop;
|
||||
|
||||
use crate::{
|
||||
@@ -16,7 +16,7 @@ use crate::{
|
||||
#[non_exhaustive]
|
||||
pub struct Inputs {
|
||||
pub key_index: u64,
|
||||
pub selector: bool,
|
||||
pub selector: PoQSelector,
|
||||
pub proof_type: ProofType,
|
||||
}
|
||||
|
||||
@@ -47,6 +47,19 @@ impl Inputs {
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn new_proof_of_work_quota_inputs(
|
||||
key_index: u64,
|
||||
proof_of_work_quota_inputs: ProofOfWorkQuotaInputs,
|
||||
) -> Self {
|
||||
let proof_type: ProofType = proof_of_work_quota_inputs.into();
|
||||
Self {
|
||||
key_index,
|
||||
selector: proof_type.proof_selector(),
|
||||
proof_type,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the right `sk` for a Proof of Quota depending on the proof type, as per the spec: <https://lip.logos.co/blockchain/raw/proof-of-quota.html#constraints>.
|
||||
#[must_use]
|
||||
pub fn get_secret_selection_randomness_sk(
|
||||
@@ -71,6 +84,10 @@ impl Inputs {
|
||||
slot_number: leadership_quota_private_inputs.slot,
|
||||
}
|
||||
}
|
||||
ProofType::PowQuota(pow_quota_private_inputs) => SelectionRandomnessSecretInput::Pow {
|
||||
pow_sk: pow_quota_private_inputs.pow_sk,
|
||||
epoch_nonce: *pol_epoch_nonce,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -79,6 +96,7 @@ impl Inputs {
|
||||
pub enum ProofType {
|
||||
CoreQuota(Box<ProofOfCoreQuotaInputs>),
|
||||
LeadershipQuota(Box<ProofOfLeadershipQuotaInputs>),
|
||||
PowQuota(Box<ProofOfWorkQuotaInputs>),
|
||||
}
|
||||
|
||||
impl Debug for ProofType {
|
||||
@@ -86,16 +104,18 @@ impl Debug for ProofType {
|
||||
match self {
|
||||
Self::CoreQuota(_) => f.write_str("ProofType::CoreQuota"),
|
||||
Self::LeadershipQuota(_) => f.write_str("ProofType::LeadershipQuota"),
|
||||
Self::PowQuota(_) => f.write_str("ProofType::PowQuota"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ProofType {
|
||||
#[must_use]
|
||||
pub const fn proof_selector(&self) -> bool {
|
||||
pub const fn proof_selector(&self) -> PoQSelector {
|
||||
match self {
|
||||
Self::CoreQuota(_) => false,
|
||||
Self::LeadershipQuota(_) => true,
|
||||
Self::CoreQuota(_) => PoQSelector::Core,
|
||||
Self::LeadershipQuota(_) => PoQSelector::Leader,
|
||||
Self::PowQuota(_) => PoQSelector::Pow,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -127,3 +147,15 @@ impl From<ProofOfLeadershipQuotaInputs> for ProofType {
|
||||
Self::LeadershipQuota(Box::new(value))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, ZeroizeOnDrop)]
|
||||
pub struct ProofOfWorkQuotaInputs {
|
||||
pub pow_sk: ZkHash,
|
||||
pub pow_block_hash: ZkHash,
|
||||
}
|
||||
|
||||
impl From<ProofOfWorkQuotaInputs> for ProofType {
|
||||
fn from(value: ProofOfWorkQuotaInputs) -> Self {
|
||||
Self::PowQuota(Box::new(value))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use core::fmt::{self, Debug, Formatter};
|
||||
|
||||
use lb_groth16::{Fr, fr_to_bytes};
|
||||
use lb_groth16::{AdditiveGroup as _, Fr, fr_to_bytes};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{ZkHash, quota::Ed25519PublicKey};
|
||||
@@ -11,6 +11,7 @@ pub struct Inputs {
|
||||
pub signing_key: Ed25519PublicKey,
|
||||
pub core: CoreInputs,
|
||||
pub leader: LeaderInputs,
|
||||
pub pow: PowInputs,
|
||||
}
|
||||
|
||||
impl Debug for Inputs {
|
||||
@@ -19,6 +20,7 @@ impl Debug for Inputs {
|
||||
.field("signing_key", &hex::encode(self.signing_key.as_bytes()))
|
||||
.field("core", &self.core)
|
||||
.field("leader", &self.leader)
|
||||
.field("pow", &self.pow)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
@@ -32,6 +34,7 @@ impl Default for Inputs {
|
||||
signing_key: Ed25519PublicKey::from_bytes(&[0; ED25519_PUBLIC_KEY_SIZE]).unwrap(),
|
||||
core: CoreInputs::default(),
|
||||
leader: LeaderInputs::default(),
|
||||
pow: PowInputs::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,3 +87,40 @@ impl Debug for LeaderInputs {
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[cfg_attr(test, derive(Default))]
|
||||
pub struct PowInputs {
|
||||
#[serde(with = "lb_groth16::serde::serde_fr")]
|
||||
pub pow_blend_difficulty: ZkHash,
|
||||
pub pow_quota: u64,
|
||||
}
|
||||
|
||||
impl PowInputs {
|
||||
/// Placeholder inputs for the `PoW` quota parameters, which are not plumbed
|
||||
/// through from the chain yet.
|
||||
///
|
||||
/// These are public inputs, so a prover and the verifier checking its
|
||||
/// proofs must use identical values. Every call site shares this single
|
||||
/// definition so they cannot drift apart.
|
||||
// TODO: Remove once the PoW quota parameters are sourced from the chain.
|
||||
#[must_use]
|
||||
pub const fn unwired_placeholder() -> Self {
|
||||
Self {
|
||||
pow_blend_difficulty: ZkHash::ZERO,
|
||||
pow_quota: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for PowInputs {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("PowInputs")
|
||||
.field(
|
||||
"pow_blend_difficulty",
|
||||
&hex::encode(fr_to_bytes(&self.pow_blend_difficulty)),
|
||||
)
|
||||
.field("pow_quota", &self.pow_quota)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,8 @@ impl From<Inputs> for PoQVerifierInput {
|
||||
.expect("Second half of signing public key does not represent a valid `Fr` point."),
|
||||
key_nullifier: value.key_nullifier,
|
||||
leader_quota: value.prove_inputs.leader.message_quota,
|
||||
pow_quota: value.prove_inputs.pow.pow_quota,
|
||||
pow_blend_difficulty: value.prove_inputs.pow.pow_blend_difficulty,
|
||||
pol_epoch_nonce: value.prove_inputs.leader.pol_epoch_nonce,
|
||||
pol_ledger_aged: value.prove_inputs.leader.pol_ledger_aged,
|
||||
lottery_0: value.prove_inputs.leader.lottery_0,
|
||||
|
||||
@@ -251,6 +251,10 @@ pub enum SelectionRandomnessSecretInput {
|
||||
note_secret_key: ZkHash,
|
||||
slot_number: u64,
|
||||
},
|
||||
Pow {
|
||||
pow_sk: ZkHash,
|
||||
epoch_nonce: ZkHash,
|
||||
},
|
||||
}
|
||||
const DOMAIN_SEPARATION_TAG: [u8; 23] = *b"SELECTION_RANDOMNESS_V1";
|
||||
static DOMAIN_SEPARATION_TAG_FR: LazyLock<ZkHash> = LazyLock::new(|| {
|
||||
@@ -268,6 +272,10 @@ fn generate_secret_selection_randomness(
|
||||
note_secret_key,
|
||||
slot_number,
|
||||
} => (note_secret_key, (*slot_number).into()),
|
||||
SelectionRandomnessSecretInput::Pow {
|
||||
pow_sk,
|
||||
epoch_nonce,
|
||||
} => (pow_sk, (*epoch_nonce)),
|
||||
};
|
||||
[
|
||||
*DOMAIN_SEPARATION_TAG_FR,
|
||||
|
||||
@@ -6,11 +6,14 @@ use lb_key_management_system_keys::keys::UnsecuredZkKey;
|
||||
use crate::{
|
||||
quota::{
|
||||
DOMAIN_SEPARATION_TAG_FR, ED25519_PUBLIC_KEY_SIZE, Ed25519PublicKey, VerifiedProofOfQuota,
|
||||
fixtures::{valid_proof_of_core_quota_inputs, valid_proof_of_leadership_quota_inputs},
|
||||
fixtures::{
|
||||
valid_proof_of_core_quota_inputs, valid_proof_of_leadership_quota_inputs,
|
||||
valid_proof_of_work_quota_inputs,
|
||||
},
|
||||
inputs::prove::{
|
||||
PrivateInputs, PublicInputs,
|
||||
private::ProofOfCoreQuotaInputs,
|
||||
public::{CoreInputs, LeaderInputs},
|
||||
public::{CoreInputs, LeaderInputs, PowInputs},
|
||||
},
|
||||
},
|
||||
selection::derive_key_nullifier_from_secret_selection_randomness,
|
||||
@@ -104,6 +107,26 @@ fn valid_proof_of_leadership_quota() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid_proof_of_work_quota() {
|
||||
let (public_inputs, private_inputs) = valid_proof_of_work_quota_inputs(
|
||||
Ed25519PublicKey::from_bytes(&[0; ED25519_PUBLIC_KEY_SIZE]).unwrap(),
|
||||
20,
|
||||
);
|
||||
|
||||
let (proof, secret_selection_randomness) = VerifiedProofOfQuota::new(
|
||||
&public_inputs,
|
||||
PrivateInputs::new_proof_of_work_quota_inputs(0, private_inputs),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let verified_proof_of_quota = proof.into_inner().verify(&public_inputs).unwrap();
|
||||
assert_eq!(
|
||||
derive_key_nullifier_from_secret_selection_randomness(secret_selection_randomness),
|
||||
verified_proof_of_quota.key_nullifier()
|
||||
);
|
||||
}
|
||||
|
||||
struct PoQInputs<const INPUTS: usize> {
|
||||
public_inputs: PublicInputs,
|
||||
secret_inputs: [ProofOfCoreQuotaInputs; INPUTS],
|
||||
@@ -137,6 +160,7 @@ fn generate_inputs<const INPUTS: usize>() -> PoQInputs<INPUTS> {
|
||||
PublicInputs {
|
||||
core: core_inputs,
|
||||
leader: leader_inputs,
|
||||
pow: PowInputs::default(),
|
||||
signing_key,
|
||||
}
|
||||
};
|
||||
@@ -254,6 +278,7 @@ fn same_key_different_indices() {
|
||||
zk_root: merkle_tree.root(),
|
||||
},
|
||||
leader: LeaderInputs::default(),
|
||||
pow: PowInputs::default(),
|
||||
signing_key: Ed25519PublicKey::from_bytes(&[10; _]).unwrap(),
|
||||
},
|
||||
secret_inputs: [ProofOfCoreQuotaInputs {
|
||||
@@ -306,6 +331,7 @@ fn different_keys_same_index() {
|
||||
zk_root: merkle_tree.root(),
|
||||
},
|
||||
leader: LeaderInputs::default(),
|
||||
pow: PowInputs::default(),
|
||||
signing_key: Ed25519PublicKey::from_bytes(&[1; _]).unwrap(),
|
||||
},
|
||||
secret_inputs: [ProofOfCoreQuotaInputs {
|
||||
|
||||
@@ -212,7 +212,7 @@ mod test {
|
||||
use lb_blend_message::crypto::proofs::PoQVerificationInputsMinusSigningKey;
|
||||
use lb_blend_proofs::quota::inputs::prove::{
|
||||
private::ProofOfLeadershipQuotaInputs,
|
||||
public::{CoreInputs, LeaderInputs},
|
||||
public::{CoreInputs, LeaderInputs, PowInputs},
|
||||
};
|
||||
use lb_core::crypto::ZkHash;
|
||||
use lb_cryptarchia_engine::Epoch;
|
||||
@@ -257,6 +257,7 @@ mod test {
|
||||
zk_root: ZkHash::ZERO,
|
||||
},
|
||||
leader: leader_inputs,
|
||||
pow: PowInputs::unwired_placeholder(),
|
||||
},
|
||||
MockCorePoQGenerator,
|
||||
Epoch::new(0),
|
||||
|
||||
@@ -124,7 +124,7 @@ mod test {
|
||||
use lb_blend_message::crypto::proofs::PoQVerificationInputsMinusSigningKey;
|
||||
use lb_blend_proofs::quota::inputs::prove::{
|
||||
private::ProofOfLeadershipQuotaInputs,
|
||||
public::{CoreInputs, LeaderInputs},
|
||||
public::{CoreInputs, LeaderInputs, PowInputs},
|
||||
};
|
||||
use lb_core::crypto::ZkHash;
|
||||
use lb_cryptarchia_engine::Epoch;
|
||||
@@ -176,6 +176,7 @@ mod test {
|
||||
zk_root: ZkHash::ZERO,
|
||||
},
|
||||
leader: initial_leader,
|
||||
pow: PowInputs::unwired_placeholder(),
|
||||
},
|
||||
MockCorePoQGenerator,
|
||||
Epoch::new(0),
|
||||
|
||||
@@ -109,6 +109,7 @@ where
|
||||
signing_key: ephemeral_signing_key.public_key().into_inner(),
|
||||
core: public_inputs.core,
|
||||
leader: public_inputs.leader,
|
||||
pow: public_inputs.pow,
|
||||
},
|
||||
key_index,
|
||||
).await.expect("Core PoQ generation should not fail.");
|
||||
|
||||
@@ -104,6 +104,7 @@ where
|
||||
let current_epoch_membership_size = self.core_proofs_generator.settings.membership_size;
|
||||
let current_epoch_core_public_inputs =
|
||||
self.core_proofs_generator.settings.public_inputs.core;
|
||||
let current_epoch_pow_public_inputs = self.core_proofs_generator.settings.public_inputs.pow;
|
||||
|
||||
self.leader_proofs_generator = Some(RealLeaderProofsGenerator::new(
|
||||
ProofsGeneratorSettings {
|
||||
@@ -113,6 +114,7 @@ where
|
||||
public_inputs: PoQVerificationInputsMinusSigningKey {
|
||||
core: current_epoch_core_public_inputs,
|
||||
leader: current_leader_inputs,
|
||||
pow: current_epoch_pow_public_inputs,
|
||||
},
|
||||
encapsulation_layers: self.core_proofs_generator.settings.encapsulation_layers,
|
||||
},
|
||||
|
||||
@@ -115,6 +115,7 @@ fn create_proof_stream(
|
||||
signing_key: ephemeral_signing_key.public_key().into_inner(),
|
||||
core: public_inputs.core,
|
||||
leader: public_inputs.leader,
|
||||
pow: public_inputs.pow,
|
||||
},
|
||||
PrivateInputs::new_proof_of_leadership_quota_inputs(
|
||||
message_release_index,
|
||||
|
||||
@@ -14,7 +14,7 @@ use lb_key_management_system_keys::keys::{ED25519_PUBLIC_KEY_SIZE, Ed25519Public
|
||||
use crate::message_blend::CoreProofOfQuotaGenerator;
|
||||
|
||||
pub const fn poq_public_inputs_from_epoch_public_inputs_and_signing_key(
|
||||
(PoQVerificationInputsMinusSigningKey { core, leader }, signing_key): (
|
||||
(PoQVerificationInputsMinusSigningKey { core, leader, pow }, signing_key): (
|
||||
PoQVerificationInputsMinusSigningKey,
|
||||
Ed25519PublicKey,
|
||||
),
|
||||
@@ -23,20 +23,26 @@ pub const fn poq_public_inputs_from_epoch_public_inputs_and_signing_key(
|
||||
signing_key: signing_key.into_inner(),
|
||||
core,
|
||||
leader,
|
||||
pow,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn valid_proof_of_quota_inputs(
|
||||
core_quota: u64,
|
||||
) -> (PoQVerificationInputsMinusSigningKey, ProofOfCoreQuotaInputs) {
|
||||
let (PoQPublicInputs { core, leader, .. }, private_inputs) = valid_proof_of_core_quota_inputs(
|
||||
let (
|
||||
PoQPublicInputs {
|
||||
core, leader, pow, ..
|
||||
},
|
||||
private_inputs,
|
||||
) = valid_proof_of_core_quota_inputs(
|
||||
Ed25519PublicKey::from_bytes(&[0; ED25519_PUBLIC_KEY_SIZE])
|
||||
.unwrap()
|
||||
.into_inner(),
|
||||
core_quota,
|
||||
);
|
||||
(
|
||||
PoQVerificationInputsMinusSigningKey { core, leader },
|
||||
PoQVerificationInputsMinusSigningKey { core, leader, pow },
|
||||
private_inputs,
|
||||
)
|
||||
}
|
||||
@@ -47,15 +53,19 @@ pub fn valid_proof_of_leader_inputs(
|
||||
PoQVerificationInputsMinusSigningKey,
|
||||
ProofOfLeadershipQuotaInputs,
|
||||
) {
|
||||
let (PoQPublicInputs { core, leader, .. }, private_inputs) =
|
||||
valid_proof_of_leadership_quota_inputs(
|
||||
Ed25519PublicKey::from_bytes(&[0; ED25519_PUBLIC_KEY_SIZE])
|
||||
.unwrap()
|
||||
.into_inner(),
|
||||
leader_quota,
|
||||
);
|
||||
let (
|
||||
PoQPublicInputs {
|
||||
core, leader, pow, ..
|
||||
},
|
||||
private_inputs,
|
||||
) = valid_proof_of_leadership_quota_inputs(
|
||||
Ed25519PublicKey::from_bytes(&[0; ED25519_PUBLIC_KEY_SIZE])
|
||||
.unwrap()
|
||||
.into_inner(),
|
||||
leader_quota,
|
||||
);
|
||||
(
|
||||
PoQVerificationInputsMinusSigningKey { core, leader },
|
||||
PoQVerificationInputsMinusSigningKey { core, leader, pow },
|
||||
private_inputs,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -104,7 +104,10 @@ mod tests {
|
||||
use std::collections::HashMap;
|
||||
|
||||
use ark_ff::AdditiveGroup as _;
|
||||
use lb_blend_proofs::{quota::VerifiedProofOfQuota, selection::VerifiedProofOfSelection};
|
||||
use lb_blend_proofs::{
|
||||
quota::{PROOF_OF_QUOTA_SIZE, VerifiedProofOfQuota},
|
||||
selection::VerifiedProofOfSelection,
|
||||
};
|
||||
use lb_groth16::{CompressedGroth16Proof, Fr};
|
||||
use lb_key_management_system_keys::keys::{Ed25519Key, Ed25519Signature, ZkKey, ZkPublicKey};
|
||||
use lb_utils::bounded::BoundedError;
|
||||
@@ -575,7 +578,8 @@ mod tests {
|
||||
let blend_proof = ActivityProof {
|
||||
epoch: 42.into(),
|
||||
signing_key: signing_key.public_key(),
|
||||
proof_of_quota: VerifiedProofOfQuota::from_bytes_unchecked([0u8; 160]).into(),
|
||||
proof_of_quota: VerifiedProofOfQuota::from_bytes_unchecked([0u8; PROOF_OF_QUOTA_SIZE])
|
||||
.into(),
|
||||
proof_of_selection: VerifiedProofOfSelection::from_bytes_unchecked([0u8; 32]).into(),
|
||||
};
|
||||
|
||||
@@ -631,7 +635,8 @@ mod tests {
|
||||
let blend_proof = ActivityProof {
|
||||
epoch: u32::MAX.into(),
|
||||
signing_key: signing_key.public_key(),
|
||||
proof_of_quota: VerifiedProofOfQuota::from_bytes_unchecked([0u8; 160]).into(),
|
||||
proof_of_quota: VerifiedProofOfQuota::from_bytes_unchecked([0u8; PROOF_OF_QUOTA_SIZE])
|
||||
.into(),
|
||||
proof_of_selection: VerifiedProofOfSelection::from_bytes_unchecked([0u8; 32]).into(),
|
||||
};
|
||||
|
||||
|
||||
Generated
+8
-8
@@ -20,17 +20,17 @@
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1781004244,
|
||||
"narHash": "sha256-zd4XYY+HPOMJXigHQDmXDvt7D1988YNPUwPPznhpFdA=",
|
||||
"lastModified": 1785937360,
|
||||
"narHash": "sha256-Id4IZ1pQ5qcTabs4fFWbfSZPHEbyDAx/3CDKv4CawII=",
|
||||
"owner": "logos-blockchain",
|
||||
"repo": "logos-blockchain-circuits",
|
||||
"rev": "2846ee7a4cfa24458bb8063412ab2e753b344d2f",
|
||||
"rev": "32f1ac43f331f0eeff3a2a0aec0f153564d03583",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "logos-blockchain",
|
||||
"ref": "v0.5.5",
|
||||
"repo": "logos-blockchain-circuits",
|
||||
"rev": "2846ee7a4cfa24458bb8063412ab2e753b344d2f",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
@@ -98,17 +98,17 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1780024773,
|
||||
"narHash": "sha256-aU9nlrS9S+IJ2EiCzsaxzOXUhggogqTrJojBicE6Oeg=",
|
||||
"lastModified": 1785302874,
|
||||
"narHash": "sha256-fpKEww3TJoo1ANHO2q918ei+ayOrp0YEQAO1DuBLOB4=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "40b0a3a193e0840c76174b4a322874c8f6dd0a63",
|
||||
"rev": "b99d48435bc3e34309d2c7ae6f7d45e77a156c38",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "40b0a3a193e0840c76174b4a322874c8f6dd0a63",
|
||||
"rev": "b99d48435bc3e34309d2c7ae6f7d45e77a156c38",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -12,13 +12,8 @@
|
||||
crane.url = "github:ipetkov/crane";
|
||||
|
||||
# Must stay in sync with the lbc-* tags in Cargo.toml.
|
||||
# Pinned to the commit right after the v0.5.3 tag (127626881faa975aa8e9868422cf6bbb08fcb512):
|
||||
# the tag itself predates the CI job that registers its Nix hashes in
|
||||
# circuits-nix-hashes.json, so building directly off the tag fails with
|
||||
# `attribute '"0.5.3"' missing`. This commit adds that entry without
|
||||
# otherwise changing the source.
|
||||
logos-blockchain-circuits = {
|
||||
url = "github:logos-blockchain/logos-blockchain-circuits/2846ee7a4cfa24458bb8063412ab2e753b344d2f";
|
||||
url = "github:logos-blockchain/logos-blockchain-circuits/v0.5.5";
|
||||
};
|
||||
|
||||
# Must stay in sync with the rust-rapidsnark rev in Cargo.toml.
|
||||
|
||||
@@ -5,7 +5,7 @@ use lb_blend_message::{
|
||||
crypto::proofs::PoQVerificationInputsMinusSigningKey,
|
||||
encap::ProofsVerifier as ProofsVerifierTrait, reward::EpochRandomness,
|
||||
};
|
||||
use lb_blend_proofs::quota::inputs::prove::public::{CoreInputs, LeaderInputs};
|
||||
use lb_blend_proofs::quota::inputs::prove::public::{CoreInputs, LeaderInputs, PowInputs};
|
||||
use lb_core::{
|
||||
crypto::ZkHash,
|
||||
mantle::Value,
|
||||
@@ -218,6 +218,7 @@ impl CurrentEpochTracker {
|
||||
quota: core_quota,
|
||||
},
|
||||
leader: leader_input,
|
||||
pow: PowInputs::unwired_placeholder(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ use lb_blend_proofs::{
|
||||
inputs::prove::{
|
||||
PrivateInputs, PublicInputs,
|
||||
private::ProofOfCoreQuotaInputs,
|
||||
public::{CoreInputs, LeaderInputs},
|
||||
public::{CoreInputs, LeaderInputs, PowInputs},
|
||||
},
|
||||
},
|
||||
selection::VerifiedProofOfSelection,
|
||||
@@ -83,6 +83,7 @@ pub fn generate_activity_proof(
|
||||
signing_key: ephemeral.public_key().into_inner(),
|
||||
core: core_inputs,
|
||||
leader: leader_inputs,
|
||||
pow: PowInputs::unwired_placeholder(),
|
||||
};
|
||||
for message_release_index in 0u64.. {
|
||||
let private_inputs = PrivateInputs::new_proof_of_core_quota_inputs(
|
||||
|
||||
@@ -30,7 +30,7 @@ use lb_blend::{
|
||||
OldEpochBlendingTokenCollector,
|
||||
},
|
||||
},
|
||||
proofs::quota::inputs::prove::public::{CoreInputs, LeaderInputs},
|
||||
proofs::quota::inputs::prove::public::{CoreInputs, LeaderInputs, PowInputs},
|
||||
scheduling::{
|
||||
EpochMessageScheduler,
|
||||
epoch::{EpochEvent, UninitializedEpochEventStream},
|
||||
@@ -604,6 +604,7 @@ where
|
||||
PoQVerificationInputsMinusSigningKey {
|
||||
core: current_epoch_public_info.poq_core_public_inputs,
|
||||
leader: current_epoch_public_info.poq_leadership_public_inputs,
|
||||
pow: PowInputs::unwired_placeholder(),
|
||||
},
|
||||
current_epoch_core_poq_generator
|
||||
.expect("Core PoQ generator must be present at startup: the proxy service only launches CoreMode when the node is part of the core membership."),
|
||||
@@ -1050,6 +1051,7 @@ where
|
||||
PoQVerificationInputsMinusSigningKey {
|
||||
core: new_epoch_info.poq_core_public_inputs,
|
||||
leader: new_epoch_info.poq_leadership_public_inputs,
|
||||
pow: PowInputs::unwired_placeholder(),
|
||||
},
|
||||
core_poq_generator,
|
||||
new_epoch_info.epoch,
|
||||
|
||||
@@ -271,7 +271,7 @@ mod tests {
|
||||
proofs::{
|
||||
quota::{
|
||||
VerifiedProofOfQuota,
|
||||
inputs::prove::public::{CoreInputs, LeaderInputs},
|
||||
inputs::prove::public::{CoreInputs, LeaderInputs, PowInputs},
|
||||
},
|
||||
selection::{self, VerifiedProofOfSelection},
|
||||
},
|
||||
@@ -305,6 +305,7 @@ mod tests {
|
||||
lottery_0: Fr::ZERO,
|
||||
lottery_1: Fr::ZERO,
|
||||
},
|
||||
pow: PowInputs::unwired_placeholder(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ use lb_blend::{
|
||||
ProofOfQuota, VerifiedProofOfQuota,
|
||||
inputs::prove::{
|
||||
private::ProofOfLeadershipQuotaInputs,
|
||||
public::{CoreInputs, LeaderInputs},
|
||||
public::{CoreInputs, LeaderInputs, PowInputs},
|
||||
},
|
||||
},
|
||||
selection::{ProofOfSelection, VerifiedProofOfSelection, inputs::VerifyInputs},
|
||||
@@ -330,6 +330,7 @@ pub fn new_crypto_processor<CorePoQGenerator>(
|
||||
PoQVerificationInputsMinusSigningKey {
|
||||
core: epoch_info.poq_core_public_inputs,
|
||||
leader: epoch_info.poq_leadership_public_inputs,
|
||||
pow: PowInputs::unwired_placeholder(),
|
||||
},
|
||||
core_poq_generator,
|
||||
epoch_info.epoch,
|
||||
|
||||
@@ -16,7 +16,7 @@ use backends::BlendBackend;
|
||||
use futures::{Stream, StreamExt as _};
|
||||
use lb_blend::{
|
||||
message::crypto::proofs::PoQVerificationInputsMinusSigningKey,
|
||||
proofs::quota::inputs::prove::public::{CoreInputs, LeaderInputs},
|
||||
proofs::quota::inputs::prove::public::{CoreInputs, LeaderInputs, PowInputs},
|
||||
scheduling::{
|
||||
epoch::{EpochEvent, UninitializedEpochEventStream},
|
||||
message_blend::provers::leader::LeaderProofsGenerator,
|
||||
@@ -425,6 +425,7 @@ where
|
||||
pol_ledger_aged: current_public_epoch_info.aged,
|
||||
message_quota: settings.epoch_leadership_quota(),
|
||||
},
|
||||
pow: PowInputs::unwired_placeholder(),
|
||||
};
|
||||
|
||||
debug!(target: LOG_TARGET, "Creating new handler for epoch {:?}", current_public_epoch_info.epoch);
|
||||
|
||||
@@ -8,12 +8,12 @@ use std::str::FromStr as _;
|
||||
use lb_pol::LotteryConstants;
|
||||
use lb_utils::math::NonNegativeRatio;
|
||||
use logos_blockchain_poq::{
|
||||
PoQBlendInputsData, PoQChainInputsData, PoQCommonInputsData, PoQWalletInputsData,
|
||||
PoQBlendInputsData, PoQChainInputsData, PoQCommonInputsData, PoQSelector, PoQWalletInputsData,
|
||||
PoQWitnessInputs,
|
||||
};
|
||||
use num_bigint::BigUint;
|
||||
|
||||
/// Quota advertised by the fixtures, for both the core and the leader branch.
|
||||
/// Quota advertised by the fixtures, for the core, the leader and pow branches.
|
||||
///
|
||||
/// It has to stay above every key index the benchmarks prove for, since the
|
||||
/// circuit only accepts indices below the quota of the branch being proven.
|
||||
@@ -24,16 +24,22 @@ fn lottery() -> (lb_groth16::Fr, lb_groth16::Fr) {
|
||||
.compute_lottery_values(5000)
|
||||
}
|
||||
|
||||
fn common_data(selector: bool, key_index: u64) -> PoQCommonInputsData {
|
||||
fn common_data(selector: PoQSelector, key_index: u64) -> PoQCommonInputsData {
|
||||
PoQCommonInputsData {
|
||||
core_quota: QUOTA,
|
||||
leader_quota: QUOTA,
|
||||
pow_quota: QUOTA,
|
||||
message_key: (
|
||||
BigUint::from(123_456u32).into(),
|
||||
BigUint::from(654_321u32).into(),
|
||||
),
|
||||
selector,
|
||||
index: key_index,
|
||||
pow_difficulty: BigUint::from_str(
|
||||
"2334035772366381927456001473031809359552034265892309520954243351196711606017",
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,8 +163,12 @@ pub fn core_node_inputs(key_index: u64) -> PoQWitnessInputs {
|
||||
.map(|(v, s)| (BigUint::from_str(v).unwrap().into(), s)),
|
||||
};
|
||||
|
||||
PoQWitnessInputs::from_core_node_data(chain_data, common_data(false, key_index), blend_data)
|
||||
.unwrap()
|
||||
PoQWitnessInputs::from_core_node_data(
|
||||
chain_data,
|
||||
common_data(PoQSelector::Core, key_index),
|
||||
blend_data,
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Witness inputs for a leadership Proof of Quota at the given key index.
|
||||
@@ -327,13 +337,17 @@ pub fn leader_inputs(key_index: u64) -> PoQWitnessInputs {
|
||||
),
|
||||
]
|
||||
.map(|(v, s)| (BigUint::from_str(v).unwrap().into(), s)),
|
||||
secret_key: BigUint::from_str(
|
||||
pol_secret_key: BigUint::from_str(
|
||||
"17558656186380761716563192806052137702710836103853413805442046164934618201080",
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
};
|
||||
|
||||
PoQWitnessInputs::from_leader_data(chain_data, common_data(true, key_index), wallet_data)
|
||||
.unwrap()
|
||||
PoQWitnessInputs::from_leader_data(
|
||||
chain_data,
|
||||
common_data(PoQSelector::Leader, key_index),
|
||||
wallet_data,
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
@@ -77,6 +77,8 @@ pub enum PoQInputsFromDataError {
|
||||
CoreQuotaMoreThan20Bits,
|
||||
#[error("Leader quota is greater than 20 bits")]
|
||||
LeaderQuotaMoreThan20Bits,
|
||||
#[error("PoW quota is greater than 20 bits")]
|
||||
PowQuotaMoreThan20Bits,
|
||||
}
|
||||
|
||||
impl TryFrom<PoQChainInputsData> for PoQChainInputs {
|
||||
|
||||
@@ -1,41 +1,59 @@
|
||||
use lb_groth16::{AdditiveGroup as _, Field as _, Fr, Groth16Input, Groth16InputDeser};
|
||||
use lb_groth16::{Fr, Groth16Input, Groth16InputDeser};
|
||||
use num_bigint::BigUint;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::chain_inputs::{
|
||||
PoQInputsFromDataError,
|
||||
PoQInputsFromDataError::{CoreQuotaMoreThan20Bits, LeaderQuotaMoreThan20Bits},
|
||||
use crate::{
|
||||
PoQInputsFromDataError::PowQuotaMoreThan20Bits,
|
||||
chain_inputs::{
|
||||
PoQInputsFromDataError,
|
||||
PoQInputsFromDataError::{CoreQuotaMoreThan20Bits, LeaderQuotaMoreThan20Bits},
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct PoQCommonInputs {
|
||||
pub core_quota: Groth16Input,
|
||||
pub leader_quota: Groth16Input,
|
||||
pub pow_quota: Groth16Input,
|
||||
pub key_part_one: Groth16Input,
|
||||
pub key_part_two: Groth16Input,
|
||||
pub selector: Groth16Input,
|
||||
pub index: Groth16Input,
|
||||
pub pow_difficulty: Groth16Input,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[repr(u8)]
|
||||
pub enum PoQSelector {
|
||||
Core = 0,
|
||||
Leader = 1,
|
||||
Pow = 2,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct PoQCommonInputsData {
|
||||
pub core_quota: u64,
|
||||
pub leader_quota: u64,
|
||||
pub pow_quota: u64,
|
||||
pub message_key: (Fr, Fr),
|
||||
pub selector: bool,
|
||||
pub selector: PoQSelector,
|
||||
pub index: u64,
|
||||
pub pow_difficulty: Fr,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct PoQCommonInputsJson {
|
||||
core_quota: Groth16InputDeser,
|
||||
leader_quota: Groth16InputDeser,
|
||||
pow_quota: Groth16InputDeser,
|
||||
#[serde(rename = "K_part_one")]
|
||||
key_part_one: Groth16InputDeser,
|
||||
#[serde(rename = "K_part_two")]
|
||||
key_part_two: Groth16InputDeser,
|
||||
selector: Groth16InputDeser,
|
||||
index: Groth16InputDeser,
|
||||
#[serde(rename = "pow_blend_difficulty")]
|
||||
pow_difficulty: Groth16InputDeser,
|
||||
}
|
||||
|
||||
impl From<&PoQCommonInputs> for PoQCommonInputsJson {
|
||||
@@ -43,19 +61,23 @@ impl From<&PoQCommonInputs> for PoQCommonInputsJson {
|
||||
PoQCommonInputs {
|
||||
core_quota,
|
||||
leader_quota,
|
||||
pow_quota,
|
||||
key_part_one,
|
||||
key_part_two,
|
||||
selector,
|
||||
index,
|
||||
pow_difficulty,
|
||||
}: &PoQCommonInputs,
|
||||
) -> Self {
|
||||
Self {
|
||||
core_quota: core_quota.into(),
|
||||
leader_quota: leader_quota.into(),
|
||||
pow_quota: pow_quota.into(),
|
||||
key_part_one: key_part_one.into(),
|
||||
key_part_two: key_part_two.into(),
|
||||
selector: selector.into(),
|
||||
index: index.into(),
|
||||
pow_difficulty: pow_difficulty.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,9 +88,11 @@ impl TryFrom<PoQCommonInputsData> for PoQCommonInputs {
|
||||
PoQCommonInputsData {
|
||||
core_quota,
|
||||
leader_quota,
|
||||
pow_quota,
|
||||
message_key,
|
||||
selector,
|
||||
index,
|
||||
pow_difficulty,
|
||||
}: PoQCommonInputsData,
|
||||
) -> Result<Self, Self::Error> {
|
||||
let leader_quota_bits = leader_quota.checked_ilog2().map_or(0, |v| v + 1);
|
||||
@@ -79,13 +103,19 @@ impl TryFrom<PoQCommonInputsData> for PoQCommonInputs {
|
||||
if core_quota_bits > 20 {
|
||||
return Err(CoreQuotaMoreThan20Bits);
|
||||
}
|
||||
let pow_quota_bits = pow_quota.checked_ilog2().map_or(0, |v| v + 1);
|
||||
if pow_quota_bits > 20 {
|
||||
return Err(PowQuotaMoreThan20Bits);
|
||||
}
|
||||
Ok(Self {
|
||||
core_quota: Groth16Input::new(Fr::from(BigUint::from(core_quota))),
|
||||
leader_quota: Groth16Input::new(Fr::from(BigUint::from(leader_quota))),
|
||||
pow_quota: Groth16Input::new(Fr::from(BigUint::from(pow_quota))),
|
||||
key_part_one: message_key.0.into(),
|
||||
key_part_two: message_key.1.into(),
|
||||
selector: Groth16Input::new(if selector { Fr::ONE } else { Fr::ZERO }),
|
||||
selector: Groth16Input::new(Fr::from(BigUint::from(selector as u8))),
|
||||
index: Groth16Input::new(Fr::from(BigUint::from(index))),
|
||||
pow_difficulty: pow_difficulty.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+62
-14
@@ -6,6 +6,7 @@ use crate::{
|
||||
blend_inputs::{PoQBlendInputs, PoQBlendInputsData, PoQBlendInputsJson},
|
||||
chain_inputs::{PoQChainInputs, PoQChainInputsJson},
|
||||
common_inputs::{PoQCommonInputs, PoQCommonInputsJson},
|
||||
pow_inputs::{PoQPowInputs, PoQPowInputsData, PoQPowInputsJson},
|
||||
wallet_inputs::{PoQWalletInputs, PoQWalletInputsData, PoQWalletInputsJson},
|
||||
};
|
||||
|
||||
@@ -16,6 +17,7 @@ pub struct PoQWitnessInputs {
|
||||
pub common: PoQCommonInputs,
|
||||
pub blend: PoQBlendInputs,
|
||||
pub wallet: PoQWalletInputs,
|
||||
pub pow: PoQPowInputs,
|
||||
}
|
||||
|
||||
impl PoQWitnessInputs {
|
||||
@@ -27,11 +29,9 @@ impl PoQWitnessInputs {
|
||||
Ok(Self {
|
||||
chain: chain.try_into()?,
|
||||
common: common.try_into()?,
|
||||
blend: PoQBlendInputs::from(PoQBlendInputsData {
|
||||
core_sk: Fr::ZERO,
|
||||
core_path_and_selectors: [(Fr::ZERO, false); _],
|
||||
}),
|
||||
blend: Self::unused_blend_inputs(),
|
||||
wallet: wallet.into(),
|
||||
pow: Self::unused_pow_inputs(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -44,14 +44,47 @@ impl PoQWitnessInputs {
|
||||
chain: chain.try_into()?,
|
||||
common: common.try_into()?,
|
||||
blend: blend.into(),
|
||||
wallet: PoQWalletInputs::from(PoQWalletInputsData {
|
||||
slot: 0,
|
||||
note_value: 0,
|
||||
transaction_hash: Fr::ZERO,
|
||||
output_number: 0,
|
||||
aged_path_and_selectors: [(Fr::ZERO, false); _],
|
||||
secret_key: Fr::ZERO,
|
||||
}),
|
||||
wallet: Self::unused_wallet_inputs(),
|
||||
pow: Self::unused_pow_inputs(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn from_pow_data(
|
||||
chain: PoQChainInputsData,
|
||||
common: PoQCommonInputsData,
|
||||
pow: PoQPowInputsData,
|
||||
) -> Result<Self, <PoQChainInputs as TryFrom<PoQChainInputsData>>::Error> {
|
||||
Ok(Self {
|
||||
chain: chain.try_into()?,
|
||||
common: common.try_into()?,
|
||||
blend: Self::unused_blend_inputs(),
|
||||
wallet: Self::unused_wallet_inputs(),
|
||||
pow: pow.into(),
|
||||
})
|
||||
}
|
||||
|
||||
fn unused_blend_inputs() -> PoQBlendInputs {
|
||||
PoQBlendInputs::from(PoQBlendInputsData {
|
||||
core_sk: Fr::ZERO,
|
||||
core_path_and_selectors: [(Fr::ZERO, false); _],
|
||||
})
|
||||
}
|
||||
|
||||
fn unused_wallet_inputs() -> PoQWalletInputs {
|
||||
PoQWalletInputs::from(PoQWalletInputsData {
|
||||
slot: 0,
|
||||
note_value: 0,
|
||||
transaction_hash: Fr::ZERO,
|
||||
output_number: 0,
|
||||
aged_path_and_selectors: [(Fr::ZERO, false); _],
|
||||
pol_secret_key: Fr::ZERO,
|
||||
})
|
||||
}
|
||||
|
||||
fn unused_pow_inputs() -> PoQPowInputs {
|
||||
PoQPowInputs::from(PoQPowInputsData {
|
||||
pow_secret_key: Fr::ZERO,
|
||||
block_hash: Fr::ZERO,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -77,6 +110,8 @@ pub struct PoQInputsJson {
|
||||
pub blend: PoQBlendInputsJson,
|
||||
#[serde(flatten)]
|
||||
pub wallet: PoQWalletInputsJson,
|
||||
#[serde(flatten)]
|
||||
pub pow: PoQPowInputsJson,
|
||||
}
|
||||
|
||||
impl From<PoQWitnessInputs> for PoQInputsJson {
|
||||
@@ -86,12 +121,13 @@ impl From<PoQWitnessInputs> for PoQInputsJson {
|
||||
chain: (&inputs.chain).into(),
|
||||
common: (&inputs.common).into(),
|
||||
blend: inputs.blend.into(),
|
||||
pow: inputs.pow.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct PoQVerifierInputJson([Groth16InputDeser; 10]);
|
||||
pub struct PoQVerifierInputJson([Groth16InputDeser; 12]);
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PoQVerifierInput {
|
||||
@@ -99,8 +135,10 @@ pub struct PoQVerifierInput {
|
||||
pub core_quota: Groth16Input,
|
||||
pub leader_quota: Groth16Input,
|
||||
pub core_root: Groth16Input,
|
||||
pub pow_quota: Groth16Input,
|
||||
pub k_part_one: Groth16Input,
|
||||
pub k_part_two: Groth16Input,
|
||||
pub pow_blend_difficulty: Groth16Input,
|
||||
pub pol_epoch_nonce: Groth16Input,
|
||||
pub pol_t0: Groth16Input,
|
||||
pub pol_t1: Groth16Input,
|
||||
@@ -112,8 +150,10 @@ pub struct PoQVerifierInputData {
|
||||
pub core_quota: u64,
|
||||
pub leader_quota: u64,
|
||||
pub core_root: Fr,
|
||||
pub pow_quota: u64,
|
||||
pub k_part_one: Fr,
|
||||
pub k_part_two: Fr,
|
||||
pub pow_blend_difficulty: Fr,
|
||||
pub pol_epoch_nonce: Fr,
|
||||
pub lottery_0: Fr,
|
||||
pub lottery_1: Fr,
|
||||
@@ -129,9 +169,11 @@ impl TryFrom<PoQVerifierInputJson> for PoQVerifierInput {
|
||||
core_quota,
|
||||
leader_quota,
|
||||
core_root,
|
||||
pow_quota,
|
||||
pol_ledger_aged,
|
||||
k_part_one,
|
||||
k_part_two,
|
||||
pow_blend_difficulty,
|
||||
pol_epoch_nonce,
|
||||
pol_t0,
|
||||
pol_t1,
|
||||
@@ -141,8 +183,10 @@ impl TryFrom<PoQVerifierInputJson> for PoQVerifierInput {
|
||||
core_quota: core_quota.try_into()?,
|
||||
leader_quota: leader_quota.try_into()?,
|
||||
core_root: core_root.try_into()?,
|
||||
pow_quota: pow_quota.try_into()?,
|
||||
k_part_one: k_part_one.try_into()?,
|
||||
k_part_two: k_part_two.try_into()?,
|
||||
pow_blend_difficulty: pow_blend_difficulty.try_into()?,
|
||||
pol_epoch_nonce: pol_epoch_nonce.try_into()?,
|
||||
pol_t0: pol_t0.try_into()?,
|
||||
pol_t1: pol_t1.try_into()?,
|
||||
@@ -153,15 +197,17 @@ impl TryFrom<PoQVerifierInputJson> for PoQVerifierInput {
|
||||
|
||||
impl PoQVerifierInput {
|
||||
#[must_use]
|
||||
pub const fn to_inputs(self) -> [Fr; 10] {
|
||||
pub const fn to_inputs(self) -> [Fr; 12] {
|
||||
[
|
||||
self.key_nullifier.into_inner(),
|
||||
self.core_quota.into_inner(),
|
||||
self.leader_quota.into_inner(),
|
||||
self.core_root.into_inner(),
|
||||
self.pow_quota.into_inner(),
|
||||
self.pol_ledger_aged.into_inner(),
|
||||
self.k_part_one.into_inner(),
|
||||
self.k_part_two.into_inner(),
|
||||
self.pow_blend_difficulty.into_inner(),
|
||||
self.pol_epoch_nonce.into_inner(),
|
||||
self.pol_t0.into_inner(),
|
||||
self.pol_t1.into_inner(),
|
||||
@@ -178,6 +224,8 @@ impl From<PoQVerifierInputData> for PoQVerifierInput {
|
||||
k_part_two: value.k_part_two.into(),
|
||||
key_nullifier: value.key_nullifier.into(),
|
||||
leader_quota: Groth16Input::new(value.leader_quota.into()),
|
||||
pow_quota: Groth16Input::new(value.pow_quota.into()),
|
||||
pow_blend_difficulty: value.pow_blend_difficulty.into(),
|
||||
pol_epoch_nonce: value.pol_epoch_nonce.into(),
|
||||
pol_ledger_aged: value.pol_ledger_aged.into(),
|
||||
pol_t0: Groth16Input::new(value.lottery_0),
|
||||
|
||||
+166
-59
@@ -2,6 +2,7 @@ mod blend_inputs;
|
||||
mod chain_inputs;
|
||||
mod common_inputs;
|
||||
mod inputs;
|
||||
mod pow_inputs;
|
||||
mod verification_key;
|
||||
mod wallet_inputs;
|
||||
mod witness;
|
||||
@@ -12,7 +13,7 @@ pub use blend_inputs::{
|
||||
CORE_MERKLE_TREE_HEIGHT, CorePathAndSelectors, PoQBlendInputs, PoQBlendInputsData,
|
||||
};
|
||||
pub use chain_inputs::{PoQChainInputs, PoQChainInputsData, PoQInputsFromDataError};
|
||||
pub use common_inputs::{PoQCommonInputs, PoQCommonInputsData};
|
||||
pub use common_inputs::{PoQCommonInputs, PoQCommonInputsData, PoQSelector};
|
||||
pub use inputs::{PoQVerifierInput, PoQVerifierInputData, PoQWitnessInputs};
|
||||
use lb_circuits_prover::Prover as _;
|
||||
use lb_groth16::{
|
||||
@@ -20,6 +21,7 @@ use lb_groth16::{
|
||||
};
|
||||
use lb_log_targets::proofs;
|
||||
pub use lb_pol::AGED_NOTE_MERKLE_TREE_HEIGHT;
|
||||
pub use pow_inputs::{PoQPowInputs, PoQPowInputsData};
|
||||
use tracing::error;
|
||||
pub use wallet_inputs::{AgedNotePathAndSelectors, PoQWalletInputs, PoQWalletInputsData};
|
||||
|
||||
@@ -141,125 +143,136 @@ mod tests {
|
||||
fn test_core_node_full_flow() {
|
||||
let blend_data = PoQBlendInputsData {
|
||||
core_sk: BigUint::from_str(
|
||||
"8905547699320869461831852104817789469875723637735901345741281588946310324235",
|
||||
"12667207762918681737213577433372645554941956657477853383508894204444641435708",
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
core_path_and_selectors: [
|
||||
(
|
||||
"16869616652852667189559016717243338331068120739649173884502336155264218010727",
|
||||
"7495929195953210541208591724669352166258167386402673863836582332959049741998",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"8777307683015870709408351814333112152804794621246499110711643849444602886454",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"13091718879067163858034522323644176312242009811093736972498389939059085177974",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"5615497624396623086866765843762273938268745340944523291991473843820399587958",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"12252618726807031528274527895794936410875679656522675436955173925070564886479",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"15676171816835539786276219242768254181009067816239948700832551985003974594975",
|
||||
"2036778247346771710692375429289939913839125337381038976370669720942761418159",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"19704272158800036501582000538191584664181486372889137807570676877252162790252",
|
||||
"5150238042344629386129384874056943525919076545561275756461664527118718260316",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"17220466132075642970726646606687934619880159579542773841528618335448239077575",
|
||||
"4936482837140898160990313117063047116523911033722639295600657041261330950251",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"8937835534203757508211957478554582398600683099364069427807070320868647534222",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"19568444328548325046015987107341253380027495775774622463368229855377989226290",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"21061581629256637244739982573784550742652688800467757972406229545047035347638",
|
||||
"20952980496079374121937279088975994236259798048934859728621453910938508315429",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"21518036264660447465371694976644098419156368727076924435365409888210990153413",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"18601741813400480889163627600644403937577783284065467384061180740490941766846",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"3276819021875171213616879397115905648698624783190949445325727117619871062684",
|
||||
"3127567055231452038159138967497074106547716639376277019791213152208715502108",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"16346413070923069365311460658994366491438423790174305844846934643885739701955",
|
||||
"4156278452715681991545944691699148599903237834447534444828105997249209183668",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"18179601246737692255359026481063507429449403349479564041630890140769203876921",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"20437752904871274044354648385284243748143753378271484669957282746297202768728",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"18052187374311288196723181314946958960293262462466262108812751192264820802527",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"18798652887540222143344482340074977888006884307412611551550673334473344453748",
|
||||
"20964128655175295722279612439890819641847965870342369257222152533521036200042",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"6340439308577685187208962346420910386234054724707742363615331612477333766009",
|
||||
"8529481264681700999783095712819666338972397694516091342589511693767349600946",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"6116045944554536720728524915454748535792176096846806949818056548601205224613",
|
||||
"11390366370077994090069924023908925478862142650386311632070176411828525668517",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"7495766221993429009053819635630800227825524659472307268648873524676590491716",
|
||||
"5917548759338686071972714539493044537194763096388397090814246211223906547270",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"20167409213677086350276694709897905285253180362287004012973310966314090006733",
|
||||
true,
|
||||
),
|
||||
(
|
||||
"4135588845309195152336413092515000771731525447810984287718633658115964724154",
|
||||
true,
|
||||
"2263236988262202014904251664760262847563737954962247776121488194923407644186",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"16515196782727402790941217652547735699069943062019512321107139568403168848690",
|
||||
true,
|
||||
"19725021492526941122134445491655907123723766494432771594886452496452660956448",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"5142311427791207713153244085802613121123367252788982353300919738927631606801",
|
||||
false,
|
||||
),
|
||||
(
|
||||
"9162839441909107733910143825064550229009975662836406280871655871464192283628",
|
||||
false,
|
||||
),
|
||||
]
|
||||
.map(|(value, selector)| (BigUint::from_str(value).unwrap().into(), selector)),
|
||||
};
|
||||
let (lottery_0, lottery_1) =
|
||||
LotteryConstants::new(NonNegativeRatio::new(1, 10.try_into().unwrap()))
|
||||
.compute_lottery_values(5000);
|
||||
let chain_data = PoQChainInputsData {
|
||||
core_root: BigUint::from_str(
|
||||
"12497635102173390657108276580981678137198622257613601634363274282193270703654",
|
||||
"8648439177578503276872559887462337398415999326614652623958174178821393732006",
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
pol_ledger_aged: BigUint::from_str(
|
||||
"3285301153701124106247898475175231377413013906491501039690975241845353257824",
|
||||
"17215820411670358459256686882934231030146782155124511326026608377144127196093",
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
pol_epoch_nonce: BigUint::from_str(
|
||||
"12441952563111122190593710132868692987264877387856913250622883462242318292882",
|
||||
"16164570534004466859325445480705051126415612717114918921927075731584584730308",
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
lottery_0: BigUint::from_str(
|
||||
"148409079361904587837471709956458430342187235603420891378597419711486680",
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
lottery_1: BigUint::from_str(
|
||||
"21888242871336145414933615591437256729835795974444825699352339602896135814447",
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
lottery_0,
|
||||
lottery_1,
|
||||
};
|
||||
let common_data = PoQCommonInputsData {
|
||||
core_quota: 15,
|
||||
leader_quota: 10,
|
||||
core_quota: 10,
|
||||
leader_quota: 15,
|
||||
pow_quota: 20,
|
||||
message_key: (
|
||||
BigUint::from(123_456u32).into(),
|
||||
BigUint::from(654_321u32).into(),
|
||||
),
|
||||
selector: false,
|
||||
index: 2,
|
||||
selector: PoQSelector::Core,
|
||||
index: 9,
|
||||
pow_difficulty: BigUint::from_str(
|
||||
"2334035772366381927456001473031809359552034265892309520954243351196711606017",
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
};
|
||||
|
||||
let witness_inputs =
|
||||
@@ -278,6 +291,8 @@ mod tests {
|
||||
k_part_two: common_data.message_key.1,
|
||||
key_nullifier,
|
||||
leader_quota: common_data.leader_quota,
|
||||
pow_quota: common_data.pow_quota,
|
||||
pow_blend_difficulty: common_data.pow_difficulty,
|
||||
pol_epoch_nonce: chain_data.pol_epoch_nonce,
|
||||
pol_ledger_aged: chain_data.pol_ledger_aged,
|
||||
lottery_0: chain_data.lottery_0,
|
||||
@@ -314,12 +329,18 @@ mod tests {
|
||||
let common_data = PoQCommonInputsData {
|
||||
core_quota: 15,
|
||||
leader_quota: 10,
|
||||
pow_quota: 5,
|
||||
message_key: (
|
||||
BigUint::from(123_456u32).into(),
|
||||
BigUint::from(654_321u32).into(),
|
||||
),
|
||||
selector: true,
|
||||
selector: PoQSelector::Leader,
|
||||
index: 2,
|
||||
pow_difficulty: BigUint::from_str(
|
||||
"2334035772366381927456001473031809359552034265892309520954243351196711606017",
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
};
|
||||
let wallet_data = PoQWalletInputsData {
|
||||
slot: 3_934_028_363,
|
||||
@@ -461,7 +482,7 @@ mod tests {
|
||||
),
|
||||
]
|
||||
.map(|(value, selector)| (BigUint::from_str(value).unwrap().into(), selector)),
|
||||
secret_key: BigUint::from_str(
|
||||
pol_secret_key: BigUint::from_str(
|
||||
"14029017592631272654768426994822986470491530234220356957377918534745805708829",
|
||||
)
|
||||
.unwrap()
|
||||
@@ -484,6 +505,92 @@ mod tests {
|
||||
k_part_two: common_data.message_key.1,
|
||||
key_nullifier,
|
||||
leader_quota: common_data.leader_quota,
|
||||
pow_quota: common_data.pow_quota,
|
||||
pow_blend_difficulty: common_data.pow_difficulty,
|
||||
pol_epoch_nonce: chain_data.pol_epoch_nonce,
|
||||
pol_ledger_aged: chain_data.pol_ledger_aged,
|
||||
lottery_0: chain_data.lottery_0,
|
||||
lottery_1: chain_data.lottery_1,
|
||||
};
|
||||
assert!(verify(&proof, recomputed_verify_inputs.into()).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pow_full_flow() {
|
||||
let chain_data = PoQChainInputsData {
|
||||
core_root: BigUint::from_str(
|
||||
"7196120816867742764244305920813414287385070139349175831448761050095304066684",
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
pol_ledger_aged: BigUint::from_str(
|
||||
"12901234158445930888471913831760642108627105440164948073754288938400615804116",
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
pol_epoch_nonce: BigUint::from_str(
|
||||
"10612486568558363932403470969435464905237449260307875593547304337083779862075",
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
lottery_0: BigUint::from_str(
|
||||
"148409079361904587837471709956458430342187235603420891378597419711486680",
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
lottery_1: BigUint::from_str(
|
||||
"21888242871336145414933615591437256729835795974444825699352339602896135814447",
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
};
|
||||
let common_data = PoQCommonInputsData {
|
||||
core_quota: 10,
|
||||
leader_quota: 15,
|
||||
pow_quota: 20,
|
||||
message_key: (
|
||||
BigUint::from(123_456u32).into(),
|
||||
BigUint::from(654_321u32).into(),
|
||||
),
|
||||
selector: PoQSelector::Pow,
|
||||
index: 8,
|
||||
pow_difficulty: BigUint::from_str(
|
||||
"10631870504716456348838861774188160492563879712126054449569633827216160699117",
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
};
|
||||
let pow_data = PoQPowInputsData {
|
||||
pow_secret_key: BigUint::from_str(
|
||||
"10044758699144566038746293679996441958807939592793641056821682251877616662024",
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
block_hash: BigUint::from_str(
|
||||
"17412116459874055221726429396167151400213699852365025340176158516975240665302",
|
||||
)
|
||||
.unwrap()
|
||||
.into(),
|
||||
};
|
||||
|
||||
let witness_inputs =
|
||||
PoQWitnessInputs::from_pow_data(chain_data, common_data, pow_data).unwrap();
|
||||
let (proof, inputs) = prove(witness_inputs).unwrap();
|
||||
let key_nullifier = inputs.key_nullifier.into_inner();
|
||||
// Test that verifying with the inputs returned by `prove` works.
|
||||
assert!(verify(&proof, inputs).unwrap());
|
||||
|
||||
// Test that verifying with the reconstructed inputs inside the verifier context
|
||||
// works.
|
||||
let recomputed_verify_inputs = PoQVerifierInputData {
|
||||
core_quota: common_data.core_quota,
|
||||
core_root: chain_data.core_root,
|
||||
k_part_one: common_data.message_key.0,
|
||||
k_part_two: common_data.message_key.1,
|
||||
key_nullifier,
|
||||
leader_quota: common_data.leader_quota,
|
||||
pow_quota: common_data.pow_quota,
|
||||
pow_blend_difficulty: common_data.pow_difficulty,
|
||||
pol_epoch_nonce: chain_data.pol_epoch_nonce,
|
||||
pol_ledger_aged: chain_data.pol_ledger_aged,
|
||||
lottery_0: chain_data.lottery_0,
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
use lb_groth16::{Fr, Groth16Input, Groth16InputDeser};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PoQPowInputs {
|
||||
pub pow_secret_key: Groth16Input,
|
||||
pub block_hash: Groth16Input,
|
||||
}
|
||||
|
||||
pub struct PoQPowInputsData {
|
||||
pub pow_secret_key: Fr,
|
||||
pub block_hash: Fr,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct PoQPowInputsJson {
|
||||
#[serde(rename = "pow_sk")]
|
||||
pow_secret_key: Groth16InputDeser,
|
||||
#[serde(rename = "pow_block_hash")]
|
||||
block_hash: Groth16InputDeser,
|
||||
}
|
||||
|
||||
impl From<PoQPowInputs> for PoQPowInputsJson {
|
||||
fn from(
|
||||
PoQPowInputs {
|
||||
pow_secret_key,
|
||||
block_hash,
|
||||
}: PoQPowInputs,
|
||||
) -> Self {
|
||||
Self {
|
||||
pow_secret_key: (&pow_secret_key).into(),
|
||||
block_hash: (&block_hash).into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PoQPowInputsData> for PoQPowInputs {
|
||||
fn from(
|
||||
PoQPowInputsData {
|
||||
pow_secret_key,
|
||||
block_hash,
|
||||
}: PoQPowInputsData,
|
||||
) -> Self {
|
||||
Self {
|
||||
pow_secret_key: pow_secret_key.into(),
|
||||
block_hash: block_hash.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ pub struct PoQWalletInputsData {
|
||||
pub transaction_hash: Fr,
|
||||
pub output_number: u64,
|
||||
pub aged_path_and_selectors: AgedNotePathAndSelectors,
|
||||
pub secret_key: Fr,
|
||||
pub pol_secret_key: Fr,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
@@ -39,7 +39,7 @@ pub struct PoQWalletInputsJson {
|
||||
#[serde(rename = "pol_noteid_path_selectors")]
|
||||
aged_selector: [Groth16InputDeser; AGED_NOTE_MERKLE_TREE_HEIGHT],
|
||||
#[serde(rename = "pol_secret_key")]
|
||||
secret_key: Groth16InputDeser,
|
||||
pol_secret_key: Groth16InputDeser,
|
||||
}
|
||||
impl From<PoQWalletInputs> for PoQWalletInputsJson {
|
||||
fn from(
|
||||
@@ -66,7 +66,7 @@ impl From<PoQWalletInputs> for PoQWalletInputsJson {
|
||||
output_number: (&pol_note_output_number).into(),
|
||||
aged_path,
|
||||
aged_selector,
|
||||
secret_key: (&pol_secret_key).into(),
|
||||
pol_secret_key: (&pol_secret_key).into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -79,12 +79,12 @@ impl From<PoQWalletInputsData> for PoQWalletInputs {
|
||||
transaction_hash,
|
||||
output_number,
|
||||
aged_path_and_selectors,
|
||||
secret_key,
|
||||
pol_secret_key,
|
||||
}: PoQWalletInputsData,
|
||||
) -> Self {
|
||||
Self {
|
||||
pol_slot: Groth16Input::new(Fr::from(BigUint::from(slot))),
|
||||
pol_secret_key: Groth16Input::new(Fr::from(BigUint::from(secret_key))),
|
||||
pol_secret_key: pol_secret_key.into(),
|
||||
pol_noteid_path_and_selectors: aged_path_and_selectors.map(|(hash, selector)| {
|
||||
(
|
||||
hash.into(),
|
||||
|
||||
Reference in New Issue
Block a user