Skip to content
Snippets Groups Projects

Add retroactive funding proposal for FCMPs

Merged Luke Parker requested to merge kayabaNerve/ccs-proposals:fcmp-retroactive into master
layout: fr
title: Retroactive funding for work on full-chain membership proofs
author: Luke Parker (kayabaNerve)
date: July 24, 2023
amount: 310 XMR
milestones:
  - name: Implementation of Bulletproofs+
    funds: 150 XMR
    done:
    status: Finished
  - name: Implementation of Curve Trees
    funds: 100 XMR
    done:
    status: Finished
  - name: Application of elliptic curve divisors for multiple times faster proofs
    funds: 50 XMR
    done:
    status: Finished
  - name: Implementation of COPZ's efficient cross-group discrete log equality proof
    funds: 10 XMR
    done:
    status: Finished
payouts:
  - date:
    amount:
  - date:
    amount:
  - date:
    amount:
  - date:
    amount:

Prior to Monerokon, I spent a month and a half working on full chain membership proofs for Monero. This is the product of

Having finished the work, which was considerable, I would like to fundraise for retroactive funding given the expenses occurred to me. Not only did I put off my own work for the significant amount of time spent on this, I made the decision to bring j-berman in at a rate we had prior established for their work on my own project.

To explain the work, it's an implementation of a membership proof compatible with Seraphis which is efficient enough to feasibly support up to 777 million outputs. For more than 777 million outputs, proof time would increase ~50%, yet the chain would continue.

While this work isn't complete, it has asserted its existence as a viable path to proceed down.

What Has Been Done

  • An implementation of Bulletproofs+, designed to be clearly understandable and efficient.

A new implementation was written despite Monero already having a deployed implementation. This was due to Monero's implementation only supporting aggregate range proofs and being so tailored for them, it being infeasible to expand to include support for arithmetic circuits (the proof Curve Trees uses).

It is not yet ready for production for a few reasons.

  1. It panics on invalid inputs, instead of returning errors.
  2. It hasn't been externally reviewed/audited.
  3. A design criteria to support curve trees is a vector commitment scheme (VCS). Bulletproofs+ does not support vector commitments, and I had to shim in my own scheme to compensate which is not viable for production.

This will be discussed below.

  • An implementation of Curve Trees, or at least, the idea of Curve Trees.

Curve Trees describes a n-ary Merkle Tree where the hash function is a Pedersen hash. Since a Pedersen hash hashes from scalars to a group element, and the variables in an arithmetic circuit are scalars, Curve Trees uses a pair of Bulletproofs over a curve cycle, each layer of the tree represented by the complimentary proof. This ensures the output of the hash is always a native variable. My implementation is similar, yet instead of using the scalar multiplication algorithm provided in its paper, Eagen's application of Elliptic Curve divisors is used. This is multiple times more performant.

Additionally, my work was done over Bulletproofs+, not Bulletproofs, for minor efficiency gains. Post-deciding which arithmetic circuit proof to use, it was learned Curve Trees requires a VCS. Bulletproofs+ does not have a VCS posited, while Bulletproofs has one posited yet not proven. While work could be done to prove the VCS posited for BPs instead of developing a new scheme for BPs+, this would be detrimental in the long term.

To explain why, BPs defines a "inner-product" argument. BPs+, "weighted inner-product". BPs++, "norm". BPs++ argues its "norm" argument can be equivalent to BPs+'s "weighted inner-product", implying future development of a VCS around BPs++ would be best done from a VCS around BPs+. Since it is a goal to move to BPs++ for efficiency, not just for arithmetic circuits (this work) yet also Monero's range proofs (which BPs++ already has funding to be reviewed for), this was kept in mind.

As part of my work, I reached out to Firo, with researcher Aram Jivanyan and contracting researcher Aaron Feickert (sarangnoether) from Cypher Stack. I requested their collaboration in this effort, with current discussions being around them working on developing and proving a VCS. While no guarantees have been made, the answer to if a scheme for BPs+'s WIP argument is possible was estimated to be on the scale of weeks, not months. Accordingly, I'd personally evaluate it within timelines and long-term fruitful to continue with BPs+ and not revert to BPs. If a BPs+ VCS is infeasible, then the work falls back to proving the VCS posited for BPs, which has passed first glances.

  • An implementation of Elliptic Curve divisor calculation and checks

Elliptic curve divisors can be used to offer proof-of-knowledge of discrete logarithms which are several times more efficient than in-circuit elliptic curve additions. I implemented the calculation of divisors, checks for them (in and out of circuit), achieving a roughly 3x reduction in DLog PoK circuit size than the Curve Trees DLog PoK circuit. This circuit is most of the overall circuit, and circuit size does directly relate to proof verification time.

  • An implementation of COPZ's discrete logarithm equality proof

Since Curve Trees effectively requires a curve cycle, Monero would have to move to one. This proof lets Monero move to a curve cycle at a marginal cost (a one-time 160-byte proof per-output).

What's Next

A series of tasks can be defined.

  1. Proving and implementing a proper VCS scheme

This is currently in progress, and doesn't actively require the Monero project. In the future, it may require our involvement, and if so, we can discuss it then.

  1. Proving/formally verifying Curve Trees

I agree more certainty behind Curve Trees is needed. I do not believe we should halt development efforts until we are fully certain, given the amount of evidence before us and alternative paths ahead of us for any road blocks we may face. Already happening is the development of a VCS scheme, with proofs. Once that happens, letting us formally define our Curve Trees instantiation, we can continue obtaining certainty. All of this can be done in parallel to this work's completion.

  1. Polishing the above work

This will be tackled by future CCSs. I am planning one, and j-berman has already submitted a CCS which part of is experimentally integrating Curve Trees into Monero (!401 (merged)). I have also discussed with multiple developers in the ecosystem getting their involvement.

To be perfectly clear, in no uncertain terms, this CCS does not provide funding for nor guarantee any continued development. It is solely a representation of gratitude and acknowledgement for work already performed, and organization provided.

  1. Auditing

Auditing can only occur once the academia, and the code, is completed.

  1. The Monero project deciding whether or not to move to a curve cycle

I cannot truly comment here as I do not speak for the Monero community.

My personal thoughts on moving to a curve cycle can be found here: https://gist.github.com/kayabaNerve/97441ad851dc6e4d2a0b699f58a004f2

Relevant MRL issues are https://github.com/monero-project/research-lab/issues/100 and https://github.com/monero-project/research-lab/issues/110.

While this isn't the place to decide if a curve cycle is necessary, or if one will be adopted, it is important to note a curve cycle isn't technically required. It's optimal, and somewhat expected, yet we can hash Ed25519 points into a cycle (at additional cost). Accordingly, this work is relevant even if we don't move to a curve cycle.

  1. The Monero project deciding whether or not to integrate this work

In order for the community to decide if this work should be integrated, it must be evaluated. Evaluation requires this work being viable for integration, which won't happen until it's complete. For now, I restate

While this work isn't complete, it has asserted its existence as a viable path to proceed down.

And accordingly justify not only its historical funding, yet future funding.

Why Historical Funding

The CCS has a distaste for historical/retroactive funding, which I understand. Personally, I do not accept payment for a job until it is done. While the milestone system offers that, I still must promise and obligate myself to doing the work by the fact I created a CCS and succesfully raised funds. I do not appreciate those obligations when I was unsure of my capabilities to produce not just a membership proof, yet a membership proof viable to continue with which was worth fundraising for. Before I wrote an implementation of BPs+, designed a higher-level arithmetic circuit framework, learned enough math to implement Elliptic Curve divisors, engaged with multiple other parties, and implemented Curve Trees, I was unsure this would become meaningful to Monero. It was on a scale I had never worked with before, and far too much work to ever be certain about before it is done and actual metrics can be assigned. Accordingly, I would never have felt comfortable with funding beforehand.

I also wished to avoid debate about the legitimacy of atttempting this work. This work, as currently implemented, with its current performance, commentary, and understandings, establishes itself as viable. Before it existed, it could not establish itself as viable. By waiting, I removed discussions about if it would be viable by now providing a proof it is.

While this work was done with limited visibility, I did contact parties as soon as they became relevant. Prior mentioned was a collaboration with Firo, yet I also reached out to Liam Eagen (author of BPs++ and a proof applying Elliptic Curve divisors), narodnik, and j-berman as beneficial.

Funds Breakdown

The amount quoted is roughly 50,000 USD. Given the amount of work produced, and time spent, I believe this to be fair.

This is inclusive of my obligation to j-berman ($3,600) who:

  • Reduced the multiplications performed, savings tens of percent off verification time
  • Investigated a new algorithm for further reducing multiplicatios, which would also be applicable to Monero's current BP+ implementation

And my desire to thank Eagen for their contributions with $5,000. Eagen's application of divisors drastically increased the performance of this work. Also notable is narodnik who provided an initial Python reference for divisor construction and evaluation, yet they have declined to be so thanked.

With all of this in mind, and given the extended hours I generally work, my hourly rate would be roughly 100 USD.

Resolution

If this proposal is not funded within two months, it will be closed regardless of status. All raised funds will be directed towards the already completed milestones, even if only partially funded. Whatever amount raised will close this CCS, and be considered as complete funding for these milestones.

Edited by Luke Parker

Merge request reports

Merged by luigi1111luigi1111 1 year ago (Dec 29, 2023 2:10am UTC)

Loading

Activity

Filter activity
  • Approvals
  • Assignees & reviewers
  • Comments (from bots)
  • Comments (from users)
  • Commits & branches
  • Edits
  • Labels
  • Lock status
  • Mentions
  • Merge request status
  • Tracking
  • Luke Parker changed the description

    changed the description

  • Luke Parker added 1 commit

    added 1 commit

    • 4ff3c1a0 - Clarify 'hourly' rate given discussion in #monero-community

    Compare with previous version

  • Luke Parker changed the description

    changed the description

  • I think everybody can agree that this would most likely have gone to funding within a week had it been proposed before the work was started.

    Usually retroactive proposals can be tricky because it puts people in a weird position when someone demands funding for something that wasn't deemed necessary by the community beforehand. With that being said, this was 100% deemed necessary by the community and kayaba was the person who decided to finally put in the work and make it a real thing.

  • An important feature of the CCS process is that the community can give feedback early on in the process, to make sure we only pay for things we actually want. This works well whenever there is a straight forward plan with concrete deliverables that are understood by the majority of the community.

    There are unfortunately very few people who understand the details of the cryptography you are using. Together with with the inherent risks of R&D its likely the community would've been overly cautions with funding the work before you started. Considering the moderate to high likelihood of R&D not working out as planned, it makes sense to work quietly instead of dealing with the additional pressure from CCS. I applaud that you were willing to effectively pre-fund your work.

    As far as I understand it FCMPs have to potential to improve or solve Moneros largest remaining privacy shortcomings, related to combining of outputs and decoy selection. There are still a lot of steps ahead, and it my not work out in the end, but we won't know unless we try. I think the potential reward is worth the risk, and we should support proposals furthering the development.

    Although it's stated that this does not fund any future work, I consider it highly unlikely that kayaba will abandon this community anytime soon. And even then, I'm convinced that he would do his best to support other devs so that they can utilize the work that has been done so far. Funding this proposal will replenish his buffer so that he can take similar risks again whenever he thinks its the best course of action.

    Making exception to rules ("no retroactive funding!") must be done carefully and with good reasons, and I think this proposal fits the criteria.

  • Was requested to make a comment providing feedback. To be clear, I am 100% for this proposal.

    On the retroactive nature of this proposal: I think contributions that certainly help move the needle on critically important tech in Monero should be rewarded. People who show up with valuable contributions, including anons with no prior history, should be paid the value of their contribution (if they want to get paid) within reason in my opinion. Establishing a stronger precedent for that I think is a good thing.

    On the general work done in this proposal: it was a well sized step toward trustless full chain membership proofs. Specifically toward answering questions:

    • Is Seraphis (and Jamtis) smoothly compatible with full chain membership proofs? (Looks like the answer may be yes.)
    • Is it possible to launch Seraphis without full chain membership proofs and then later implement reasonably efficient full chain membership proofs without needing users to migrate addresses again? (Looks like the answer is yes.)
    • Does Seraphis include anything that renders full chain membership proofs particularly more challenging to implement or perpetually less efficient? (Looks like the answer may be no depending on the route taken.)

    This work is critically important toward routing a potential major upgrade path. It's therefore critically important work.

    On my work done in this proposal: I put in a fairly solid chunk of time to help bring verification time down a significant amount and explored a route where it could be brought down further and which could benefit Monero today (without a fork). The latter work is still potentially worth further exploration to bring verification time down some small % today (I think it's probably closer to a micro optimization though). I figure it is self evident why this work is useful toward helping gauge the efficiency of full chain membership proofs as proposed.

    • Contributor
      1. As this proposal is being upvoted (exclusively?) by non-devs, I would like to see more endorsements by other devs who deem the work "worthy" (at the given rate) of further exploration, especially people involved with Seraphis (i.e. @rbrunner7, @UkoeHB & others). We should also be able to see in meeting minutes from either -dev or -research-lab that the work has been gaining traction and attracting contributors. No offense to @j-berman, but a single developer endorsement by someone who is an indirect beneficiary of this proposal is not enough.

      2. Another issue is that these funds are being raised retroactively without anything concrete having been produced. Yes, a path of exploration has been established, great. How much longer do we keep exploring that path before pull requests start getting merged? Is $50,000 for a month and a half of work a rate of exploration that we can sustain?

      3. Making an exception to the rule ("no retroactive funding!") is one thing. Establishing that this is an accepted way of working and receiving another $50,000 request for retroactive funding two months from now, without any merged PRs yet again, is something else. Even the author of Seraphis didn't request retroactive funding for writing the Seraphis paper or the initial PoC code.

      If this gets merged, we would establish that retroactive funding requests are OK, without any hourly or monthly limits, without any end in sight, and even when they haven't produced anything tangible.

    • I was wrong there is no explicit rule on retroactive funding, at least not on the official page

      That said, the CCS has retroactively awarded funds to projects were the main work was completed. Technically those funds were intended to cover "finalizing" fees, but I don't see much practical difference to this proposal: in neither case the CCS participants were able to discuss the work before it was done, meaning step 3-5 of the CCS proposal standard flow were skipped.

      Unlike the other project, the concrete results of this FCMP proposals were publicly available at all times, as the required by CCS proposer rule #4.

      Yes, funding this would indeed set a precedent. It be a clear sign from the community that we won't cheap out on important dev work, such as work on core monero code. I'm sure our highly skilled devs could easily choose to work somewhere else, and developing for Monero is risky enough as-is, so I don't think it is smart to be splitting hairs over unwritten rules.

    • Please register or sign in to reply
    1. I do invite other developers to comment. So far, I've talked with Aaron and Koe at Monerokon, though I ack the lack of comments here.

    2. I wrote an entire ZK framework and a full implementation of the proof as necessary for composability within Seraphis. I then spent weeks optimizing it. While you may say there's nothing concrete produced, as there's yet to be a PR to Monero, that's dismissive of all the work I've done. I'd also point out several important CCSs have also failed to produce PRs to Monero immediately. We recently funded an audit of BP++, as a paper, which will yield zero PRs to Monero. Solely exploration of proof security in order to determine viability.

    jberman's recent CCS would start integration into Monero and produce more 'concrete' results.

    1. There is no such rule. If there was such a role, I'd call for it to be struck given I believe there's plenty of legitimate reasons to post-request funds. Since there is no such rule, I don't have to, yet I did still include my reasoning within this proposal.
  • Author Contributor

    ^ I did mess up which account I logged in with to reply, sorry, yet can confirm that is me.

  • Just gave my "thumbs up", encouraged by @geonic1 asking for feedback from devs.

    This work already done, and @j-berman probably getting the chance to build it into an experimental Seraphis capable Monero codebase, will give us the very attractive chance to go beyond mere speculation and really try out firsthand whether this thing flies or not.

    If it does I can see us going for it. The switch to Seraphis is already a monumental undertaking, with or without this, I think we could afford to put this on top.

  • Retroactive fundings being a sensitive issue it would be good to have a detailed breakdown of time spent on various tasks rather than simply a global amount so as to avoid the type of discussions which happened over MK reimbursements when just an amount was provided.

    As the work has already been done this should be rather easy to add.

  • Author Contributor

    While I don't care for deliverable/hourly squabbles, I'll note my received amount will be 41,400. Off hand, I spent roughly 6 weeks at 10 hours a day, and no, I do not generally take weekends. 6 * 7 * 10 = 420. This would create an hourly rate of ~$100, which was the agreed upon rate with j-berman for their work (meaning their hour count is a strict 36 hours for achieving, at the time, IIRC 20% improvements, and further research into a more efficient algorithm which would surpass Monero's own).

    I could create a more detailed hour log based off the commits. I don't care to spend the hours (3-6?) it'd take. For anyone doubting I actually work that much, I checked my work today. I checked in yesterday at 6pm and it's currently 11am. Allotting an hour for dinner, and two hours for the exercise I did + other loose items... That would be 17h - 3h so far. My git history alone verifies commits from 14h ago (building on review I was doing locally) continuing to now. Given the 6 weeks is inconclusive to work I did on this BP+ impl prior to this dedicated effort, and some optimizations which continued while traveling (though not at a 10h a day work rate, of course), I'm legitimately unsure if an actual hour log would be lower or higher. I do feel it's a fair estimate.

    If you want a breakdown on specific tasks, I'm unsure why. While we can look back on how long specific parts took, and then judge me for taking as long (or working as quickly) as I did compared to estimates, that doesn't change the fact that the work took as long as it did in reality. Given a month and a half overall, for the overall work produced, doesn't seem unreasonable I don't feel such questions are necessary.

    Please feel free to comment if there's an angle I'm missing. I apologize if I'm not understanding your interest.

    Edited by Luke Parker
  • I have no doubts about the amount of work you may produce, I am just pointing out that we've had drama in the Monero community for far lower amounts which lacked details (reimbursements for MK), so I am being cautious about the precedent a retroactive funding without detailed breakdown could set.

  • The move to FCMPs, if we choose to go down this route, will be one of the biggests, if not the single biggest, boons to privacy Monero has ever seen. While I don't claim to be an expert in this area of cryptography, the work that Luke has put into making sure that FCMPs are compatible with Seraphis/Jamtis in solid by all accounts that I have seen. The value that said work will likely bring to Monero is positively enormous, surely greater than $40,000 or however much the XMR is valued at the time of writing. This proposal is special in the sense that there likely won't be very many more academic/research breakthoughs of this magnitude. Luke, to me, has laid out very understandable (and community-focused) reasons for why this proposal didn't ask for funding beforehand: it was not known if it was possible to be done in the way that it was.

    One point I want to hammer home: Luke could be working anywhere else for much, much more money. I personally love the Monero project with a passion, which is why I choose to allocate so much time to it. I personally have been offered more money to work in other fields, even other crypto projects. Luke far outstrips me in terms of cryptographic and mathematical knowledge and skill, so I doubt that Luke is sticking with CCS funding for the riches. The comparatively small amount of retroactive funding (honestly it could be greater) that this proposal asks for is justified IMHO.

    This proposal has my approval.

  • Just a reminder: !107 (closed)

    Personally I support reactive requests for funding. Work done is work done, and if it benefits the project and people wish to donate, I don't see the problem. So for clarity, I support this.

    Edited by Jethro Grassie
  • Contributor

    It has been a long-standing policy of the CCS not to allow retroactive funding. Even in the broader economy, retroactive funding is seldom if ever found. This is because it creates an asymmetry between the recipient and funders which undermines trust and independence.

    In this case, it would be more appropriate to solicit independent donations (the long-established route for already-completed open source work). For future projects where the value of the outcome is uncertain ex ante, it may be worthwhile to establish an open-ended bounty system for significant research contributions to Monero.

    Edited by koe
  • Contributor

    Thanks @jtgrassie for the reminder. Although that proposal was closed, it had a lot more going for it than what's being discussed here -- RandomX was actually delivered and functioning, not just a promise. I'm as eager as @rbrunner7 is to see if this thing flies or not, but we won't get this with this proposal. What we most certaily will get is more proposals for past work that we had no say over and that has not produced any concrete results. This may be an opportunity to codify the policy into a rule, as @luigi1111 said:

    For project or new potential on-going person-type CCSes, I really want to get away from the notion of getting paid for prior work. This may require adding a new rule regarding such.

    I love @koe's idea of establishing an open-ended bounty system for significant research contributions. A $50k bounty towards FCMPs would be a great start. I also agree that this fundraising mode shifts the balance of power way too far towards the recipient.

    Another problematic aspect of this proposal that hasn't been discussed yet is the proposer's offers (i.e. promises) of payments and "gifts" with amounts that he expected to raise via CCS. Neither the $3600 payment to jberman or the $5000 "gift" to Liam Eagen (a Blockstream employee), which the proposer promised, has been made yet. I'm glad that narodnik rejected the generous gift offer that was made to him, which we would also be on the hook for. These offers put a lot of pressure on us to approve this proposal or risk tarnishing our reputation as a community in the broader ecosystem.

  • Author Contributor

    That is an unfair misconstruction of what has occurred.

    1. I hired j-berman. If this does not go through, I will honor my debt and have no complaints about it. I am perfectly fine having donated that money to the project's benefit, if that's how things end up. j-berman obviously understands how the CCS works and is not applying societal pressure.

    2. Regarding Eagen and narodnik, both were offered positions in this CCS under the scope of retroactive funding. Neither were offered any guaranteed funding, so there is no such reputational risk to Monero. I believed it unfair to request retroactive funding for myself and myself alone when other parties of significance existed. If you are concerned either party will be/would have been disappointed, that disappointment would only come from the CCS's views on retroactive funding and the lengthy debates which plague it. Not because of any actions of mine.

    --

    Distinctly, regarding further work on FCMPs, a traditional CCSs by j-berman has been done and I plan to do a traditional CCS for further development as well. Accordingly, I don't see a need for establishment of a bounty for FCMPs specifically at this time. I'd also note a 50k bounty, depending on the scope required for it to be issued, would likely be far too low to not be considerable solely as a donation (not payment, as even the low end of payment for increased scope would likely be 2-3x more).

    --

    While I don't mind the debate, as I value the community's opinions and don't necessarily expect funding, I will say it can be tiring. We've lost great contributors to Monero before over how exhausting the CCS process can be. While that's not a risk here, as I plan to still contribute to Monero regardless of if this is funded, a risk I accepted when I decided to retro-actively fund and not pro-actively fund, I hope this isn't extended too much longer due to how draining it is.

    I would like to explicitly say, yet again, I am fine if this is not funded. While I'll be disappointed if it isn't, I will understand if the CCS stands against retroactive funding. While I'll disagree with that decision, I will acknowledge it's not my decision and move on.

    Due to the commentary that this proposal is pressuring the community in some way*, I'd call for this CCS to be paused entirely until a competent policy on retroactive funding is created. Any piece of those discussions which refer to this standing (on pause) proposal as reasoning for policy should be struck (in order to prevent pressure), though the example of work here with the reasons included would be valuable insight IMO. While I don't believe this is the right move, I'd rather do it and have this CCS closed than be viewed as someone of impropriety.

    *The pressure is due to asking for funding for completed work, suggesting an obligation from the community. While I do not perceive such an obligation, and have stated so, I understand if others believe one is implied even if that's not my intent. My argument for this CCS has always been on the work, not on the fact the work is already done. It solely happens to already be done.

  • I would like to give a vote for a pragmatic approach.

    While the "contract" governing the CCS here makes it clear that the CCS Proposal Standard Flow is funding first, work afterwards, it also says: "The CCS is intentionally left as informal as possible. This allows for flexibility of the system", and nowhere it explicitely forbids retroactive proposals.

    If a contract does not forbid something that it should, seems to me the usual reaction is to modify the contract, but let things stand that happened while the original contract was in force. You usually don't make retroactive contract changes.

    This leads me to vote for letting this proposal here through and move it to funding, as probably the last such retroactive one.

  • For the record, I was aware from the start kayaba intended to make a CCS for retroactive funding and I supported kayaba's decision to do so because I figured this endeavor would be a clear demonstration to the community why retroactive funding can be useful and reasonable. When I agreed to kayaba's deal, similar to kayaba, I was also unsure if my work would pan out successfully nor did I know if it would take me a reasonable amount of time, so I wasn't comfortable opening a CCS to do my slice of work at that time. The completion of this work gave me the confidence to include continuing work on it in my latest proactive CCS.

    An open-ended bounty would have been a fine alternative. But I generally do believe retroactive funding is a sensible tool the CCS can wield to bring maximum benefit to Monero's code, if used correctly. I understand the view against it as well and how establishing a strong precedent for it can open the CCS for abuse. I think it is like any tool in that it can be used incorrectly. I believe this set of circumstances demonstrates why it's a powerful and useful tool that can be wielded to benefit Monero.

  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
  • Loading
Please register or sign in to reply
Loading