level_up.rs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. /*! A module for the protocol for the user to increase their trust level
  2. (from a level at least 1; use the trust promotion protocol to go from
  3. untrusted (level 0) to minimally trusted (level 1).
  4. They are allowed to do this as long as some amount of time (depending on
  5. their current level) has elapsed since their last level change, and they
  6. have a Bucket Reachability credential for their current bucket and
  7. today's date. (Such credentials are placed daily in the encrypted
  8. bridge table.)
  9. The user presents their current Lox credential:
  10. - id: revealed
  11. - bucket: blinded
  12. - trust_level: revealed, and must be at least 1
  13. - level_since: blinded, but proved in ZK that it's at least the
  14. appropriate number of days ago
  15. - invites_remaining: blinded
  16. - invites_issued: blinded
  17. and a Bucket Reachability credential:
  18. - date: revealed to be today
  19. - bucket: blinded, but proved in ZK that it's the same as in the Lox
  20. credential above
  21. and a new Lox credential to be issued:
  22. - id: jointly chosen by the user and BA
  23. - bucket: blinded, but proved in ZK that it's the same as in the Lox
  24. credential above
  25. - trust_level: revealed to be one more than the trust level above
  26. - level_since: today
  27. - invites_remaining: revealed to be the number of invites for the new
  28. level (note that the invites_remaining from the previous credential
  29. are _not_ carried over)
  30. - invites_issued: blinded, but proved in ZK that it's the same as in the
  31. Lox credential above
  32. */
  33. use curve25519_dalek::ristretto::RistrettoBasepointTable;
  34. use curve25519_dalek::ristretto::RistrettoPoint;
  35. use curve25519_dalek::scalar::Scalar;
  36. use curve25519_dalek::traits::IsIdentity;
  37. use zkp::CompactProof;
  38. use zkp::ProofError;
  39. use zkp::Transcript;
  40. use super::super::cred;
  41. use super::super::dup_filter::SeenType;
  42. use super::super::{pt_dbl, scalar_dbl, scalar_u32};
  43. use super::super::{BridgeAuth, IssuerPubKey};
  44. use super::super::{CMZ_A, CMZ_A_TABLE, CMZ_B, CMZ_B_TABLE};
  45. /// The maximum trust level in the system. A user can run this level
  46. /// upgrade protocol when they're already at the max level; they will
  47. /// get a fresh invites_remaining batch, and reset their level_since
  48. /// field to today's date, but will remain in the max level.
  49. pub const MAX_LEVEL: usize = 3;
  50. /// LEVEL_INTERVAL\[i\] for i >= 1 is the minimum number of days a user
  51. /// must be at trust level i before advancing to level i+1 (or as above,
  52. /// remain at level i if i == MAX_LEVEL). Note that the
  53. /// LEVEL_INTERVAL\[0\] entry is a dummy; the trust_promotion protocol
  54. /// is used instead of this one to move from level 0 to level 1.
  55. pub const LEVEL_INTERVAL: [u32; MAX_LEVEL + 1] = [0, 14, 28, 56];
  56. /// LEVEL_INVITATIONS\[i\] for i >= 1 is the number of invitations a
  57. /// user will be eligible to issue upon advancing from level i to level
  58. /// i+1. Again the LEVEL_INVITATIONS\[0\] entry is a dummy, as for
  59. /// LEVEL_INTERVAL.
  60. pub const LEVEL_INVITATIONS: [u32; MAX_LEVEL + 1] = [0, 2, 4, 6];
  61. pub struct Request {
  62. // Fields for blind showing the Lox credential
  63. P: RistrettoPoint,
  64. id: Scalar,
  65. CBucket: RistrettoPoint,
  66. level: Scalar,
  67. CSince: RistrettoPoint,
  68. CInvRemain: RistrettoPoint,
  69. CInvIssued: RistrettoPoint,
  70. CQ: RistrettoPoint,
  71. // Fields for blind showing the Bucket Reachability credential
  72. P_reach: RistrettoPoint,
  73. CBucket_reach: RistrettoPoint,
  74. CQ_reach: RistrettoPoint,
  75. // Fields for the inequality proof (level_since +
  76. // LEVEL_INTERVAL[level] <= today)
  77. CG1: RistrettoPoint,
  78. CG2: RistrettoPoint,
  79. CG3: RistrettoPoint,
  80. CG4: RistrettoPoint,
  81. CG5: RistrettoPoint,
  82. CG6: RistrettoPoint,
  83. CG7: RistrettoPoint,
  84. CG8: RistrettoPoint,
  85. CG0sq: RistrettoPoint,
  86. CG1sq: RistrettoPoint,
  87. CG2sq: RistrettoPoint,
  88. CG3sq: RistrettoPoint,
  89. CG4sq: RistrettoPoint,
  90. CG5sq: RistrettoPoint,
  91. CG6sq: RistrettoPoint,
  92. CG7sq: RistrettoPoint,
  93. CG8sq: RistrettoPoint,
  94. // Fields for user blinding of the Lox credential to be issued
  95. D: RistrettoPoint,
  96. EncIdClient: (RistrettoPoint, RistrettoPoint),
  97. EncBucket: (RistrettoPoint, RistrettoPoint),
  98. EncInvIssued: (RistrettoPoint, RistrettoPoint),
  99. // The combined ZKP
  100. piUser: CompactProof,
  101. }
  102. #[derive(Debug)]
  103. pub struct State {
  104. d: Scalar,
  105. D: RistrettoPoint,
  106. EncIdClient: (RistrettoPoint, RistrettoPoint),
  107. EncBucket: (RistrettoPoint, RistrettoPoint),
  108. EncInvIssued: (RistrettoPoint, RistrettoPoint),
  109. id_client: Scalar,
  110. bucket: Scalar,
  111. level: Scalar,
  112. invremain: Scalar,
  113. invissued: Scalar,
  114. }
  115. pub struct Response {
  116. // The fields for the new Lox credential; the new trust level is one
  117. // more than the old trust level, so we don't have to include it
  118. // here explicitly
  119. P: RistrettoPoint,
  120. EncQ: (RistrettoPoint, RistrettoPoint),
  121. id_server: Scalar,
  122. level_since: Scalar,
  123. TId: RistrettoPoint,
  124. TBucket: RistrettoPoint,
  125. TInvRemain: RistrettoPoint,
  126. TInvIssued: RistrettoPoint,
  127. // The fields for the implicit noop migration ("nm") credential
  128. P_nm: RistrettoPoint,
  129. EncQ_nm: (RistrettoPoint, RistrettoPoint),
  130. TId_nm: RistrettoPoint,
  131. TBucket_nm: RistrettoPoint,
  132. // The ZKP
  133. piBlindIssue: CompactProof,
  134. }
  135. define_proof! {
  136. requestproof,
  137. "Level Upgrade Request",
  138. (bucket, since, invremain, invissued, zbucket, zsince, zinvremain,
  139. zinvissued, negzQ,
  140. zbucket_reach, negzQ_reach,
  141. d, eid_client, ebucket, einvissued, id_client,
  142. g0, g1, g2, g3, g4, g5, g6, g7, g8,
  143. zg0, zg1, zg2, zg3, zg4, zg5, zg6, zg7, zg8,
  144. wg0, wg1, wg2, wg3, wg4, wg5, wg6, wg7, wg8,
  145. yg0, yg1, yg2, yg3, yg4, yg5, yg6, yg7, yg8),
  146. (P, CBucket, CSince, CInvRemain, CInvIssued, V, Xbucket, Xsince,
  147. Xinvremain, Xinvissued,
  148. P_reach, CBucket_reach, V_reach, Xbucket_reach,
  149. D, EncIdClient0, EncIdClient1, EncBucket0, EncBucket1,
  150. EncInvIssued0, EncInvIssued1,
  151. CG0, CG1, CG2, CG3, CG4, CG5, CG6, CG7, CG8,
  152. CG0sq, CG1sq, CG2sq, CG3sq, CG4sq, CG5sq, CG6sq, CG7sq, CG8sq),
  153. (A, B) :
  154. // Blind showing of the Lox credential
  155. CBucket = (bucket*P + zbucket*A),
  156. CSince = (since*P + zsince*A),
  157. CInvRemain = (invremain*P + zinvremain*A),
  158. CInvIssued = (invissued*P + zinvissued*A),
  159. // Blind showing of the Bucket Reachability credential; note the
  160. // same bucket is used in the proof
  161. CBucket_reach = (bucket*P_reach + zbucket_reach*A),
  162. // User blinding of the Lox credential to be issued
  163. D = (d*B),
  164. EncIdClient0 = (eid_client*B),
  165. EncIdClient1 = (id_client*B + eid_client*D),
  166. EncBucket0 = (ebucket*B),
  167. EncBucket1 = (bucket*B + ebucket*D),
  168. EncInvIssued0 = (einvissued*B),
  169. EncInvIssued1 = (invissued*B + einvissued*D),
  170. // Prove CSince encodes a value at least LEVEL_INTERVAL
  171. // days ago (at technically at most LEVEL_INTERVAL+511 days
  172. // ago): first prove each of g0, ..., g8 is a bit by proving that
  173. // gi = gi^2
  174. CG0 = (g0*P + zg0*A), CG0sq = (g0*CG0 + wg0*A), CG0sq = (g0*P + yg0*A),
  175. CG1 = (g1*P + zg1*A), CG1sq = (g1*CG1 + wg1*A), CG1sq = (g1*P + yg1*A),
  176. CG2 = (g2*P + zg2*A), CG2sq = (g2*CG2 + wg2*A), CG2sq = (g2*P + yg2*A),
  177. CG3 = (g3*P + zg3*A), CG3sq = (g3*CG3 + wg3*A), CG3sq = (g3*P + yg3*A),
  178. CG4 = (g4*P + zg4*A), CG4sq = (g4*CG4 + wg4*A), CG4sq = (g4*P + yg4*A),
  179. CG5 = (g5*P + zg5*A), CG5sq = (g5*CG5 + wg5*A), CG5sq = (g5*P + yg5*A),
  180. CG6 = (g6*P + zg6*A), CG6sq = (g6*CG6 + wg6*A), CG6sq = (g6*P + yg6*A),
  181. CG7 = (g7*P + zg7*A), CG7sq = (g7*CG7 + wg7*A), CG7sq = (g7*P + yg7*A),
  182. CG8 = (g8*P + zg8*A), CG8sq = (g8*CG8 + wg8*A), CG8sq = (g8*P + yg8*A)
  183. // Then we'll check that CSince + LEVEL_INTERVAL*P + CG0 + 2*CG1
  184. // + 4*CG2 + 8*CG3 + ... + 256*CG8 = today*P by having the verifier
  185. // plug in today*P - (CSince + LEVEL_INTERVAL*P + 2*CG1 + 4*CG2
  186. // + ... + 256*CG8) as its value of CG0.
  187. }
  188. pub fn request(
  189. lox_cred: &cred::Lox,
  190. reach_cred: &cred::BucketReachability,
  191. lox_pub: &IssuerPubKey,
  192. reach_pub: &IssuerPubKey,
  193. today: u32,
  194. ) -> Result<(Request, State), ProofError> {
  195. let A: &RistrettoPoint = &CMZ_A;
  196. let B: &RistrettoPoint = &CMZ_B;
  197. let Atable: &RistrettoBasepointTable = &CMZ_A_TABLE;
  198. let Btable: &RistrettoBasepointTable = &CMZ_B_TABLE;
  199. // Ensure the credential can be correctly shown: it must be the case
  200. // that level_since + LEVEL_INTERVAL[level] <= today.
  201. let level_since: u32 = match scalar_u32(&lox_cred.level_since) {
  202. Some(v) => v,
  203. None => return Err(ProofError::VerificationFailure),
  204. };
  205. // The trust level has to be at least 1
  206. let trust_level: u32 = match scalar_u32(&lox_cred.trust_level) {
  207. Some(v) => v,
  208. None => return Err(ProofError::VerificationFailure),
  209. };
  210. if trust_level < 1 {
  211. return Err(ProofError::VerificationFailure);
  212. }
  213. // The trust level has to be no higher than the highest level
  214. let level_interval: u32 = match LEVEL_INTERVAL.get(trust_level as usize) {
  215. Some(&v) => v,
  216. None => return Err(ProofError::VerificationFailure),
  217. };
  218. if level_since + level_interval > today {
  219. return Err(ProofError::VerificationFailure);
  220. }
  221. // The credential can't be _too_ old
  222. let diffdays = today - (level_since + level_interval);
  223. if diffdays > 511 {
  224. return Err(ProofError::VerificationFailure);
  225. }
  226. // The buckets in the Lox and Bucket Reachability credentials have
  227. // to match
  228. if lox_cred.bucket != reach_cred.bucket {
  229. return Err(ProofError::VerificationFailure);
  230. }
  231. // The Bucket Reachability credential has to be dated today
  232. let reach_date: u32 = match scalar_u32(&reach_cred.date) {
  233. Some(v) => v,
  234. None => return Err(ProofError::VerificationFailure),
  235. };
  236. if reach_date != today {
  237. return Err(ProofError::VerificationFailure);
  238. }
  239. // Blind showing the Lox credential
  240. // Reblind P and Q
  241. let mut rng = rand::thread_rng();
  242. let t = Scalar::random(&mut rng);
  243. let P = t * lox_cred.P;
  244. let Q = t * lox_cred.Q;
  245. // Form Pedersen commitments to the blinded attributes
  246. let zbucket = Scalar::random(&mut rng);
  247. let zsince = Scalar::random(&mut rng);
  248. let zinvremain = Scalar::random(&mut rng);
  249. let zinvissued = Scalar::random(&mut rng);
  250. let CBucket = lox_cred.bucket * P + &zbucket * Atable;
  251. let CSince = lox_cred.level_since * P + &zsince * Atable;
  252. let CInvRemain = lox_cred.invites_remaining * P + &zinvremain * Atable;
  253. let CInvIssued = lox_cred.invites_issued * P + &zinvissued * Atable;
  254. // Form a Pedersen commitment to the MAC Q
  255. // We flip the sign of zQ from that of the Hyphae paper so that
  256. // the ZKP has a "+" instead of a "-", as that's what the zkp
  257. // macro supports.
  258. let negzQ = Scalar::random(&mut rng);
  259. let CQ = Q - &negzQ * Atable;
  260. // Compute the "error factor"
  261. let V = zbucket * lox_pub.X[2]
  262. + zsince * lox_pub.X[4]
  263. + zinvremain * lox_pub.X[5]
  264. + zinvissued * lox_pub.X[6]
  265. + &negzQ * Atable;
  266. // Blind showing the Bucket Reachability credential
  267. // Reblind P and Q
  268. let t_reach = Scalar::random(&mut rng);
  269. let P_reach = t_reach * reach_cred.P;
  270. let Q_reach = t_reach * reach_cred.Q;
  271. // Form Pedersen commitments to the blinded attributes
  272. let zbucket_reach = Scalar::random(&mut rng);
  273. let CBucket_reach = reach_cred.bucket * P_reach + &zbucket_reach * Atable;
  274. // Form a Pedersen commitment to the MAC Q
  275. // We flip the sign of zQ from that of the Hyphae paper so that
  276. // the ZKP has a "+" instead of a "-", as that's what the zkp
  277. // macro supports.
  278. let negzQ_reach = Scalar::random(&mut rng);
  279. let CQ_reach = Q_reach - &negzQ_reach * Atable;
  280. // Compute the "error factor"
  281. let V_reach = zbucket_reach * reach_pub.X[2] + &negzQ_reach * Atable;
  282. // User blinding for the Lox certificate to be issued
  283. // Pick an ElGamal keypair
  284. let d = Scalar::random(&mut rng);
  285. let D = &d * Btable;
  286. // Pick a random client component of the id
  287. let id_client = Scalar::random(&mut rng);
  288. // Encrypt it (times the basepoint B) to the ElGamal public key D we
  289. // just created
  290. let eid_client = Scalar::random(&mut rng);
  291. let EncIdClient = (&eid_client * Btable, &id_client * Btable + eid_client * D);
  292. // Encrypt the other blinded fields (times B) to D as well
  293. let ebucket = Scalar::random(&mut rng);
  294. let EncBucket = (&ebucket * Btable, &lox_cred.bucket * Btable + ebucket * D);
  295. let newinvites: Scalar = LEVEL_INVITATIONS[trust_level as usize].into();
  296. let einvissued = Scalar::random(&mut rng);
  297. let EncInvIssued = (
  298. &einvissued * Btable,
  299. &lox_cred.invites_issued * Btable + einvissued * D,
  300. );
  301. // The range proof that 0 <= diffdays <= 511
  302. // Extract the 9 bits from diffdays
  303. let g0: Scalar = (diffdays & 1).into();
  304. let g1: Scalar = ((diffdays >> 1) & 1).into();
  305. let g2: Scalar = ((diffdays >> 2) & 1).into();
  306. let g3: Scalar = ((diffdays >> 3) & 1).into();
  307. let g4: Scalar = ((diffdays >> 4) & 1).into();
  308. let g5: Scalar = ((diffdays >> 5) & 1).into();
  309. let g6: Scalar = ((diffdays >> 6) & 1).into();
  310. let g7: Scalar = ((diffdays >> 7) & 1).into();
  311. let g8: Scalar = ((diffdays >> 8) & 1).into();
  312. // Pick random factors for the Pedersen commitments
  313. let wg0 = Scalar::random(&mut rng);
  314. let zg1 = Scalar::random(&mut rng);
  315. let wg1 = Scalar::random(&mut rng);
  316. let zg2 = Scalar::random(&mut rng);
  317. let wg2 = Scalar::random(&mut rng);
  318. let zg3 = Scalar::random(&mut rng);
  319. let wg3 = Scalar::random(&mut rng);
  320. let zg4 = Scalar::random(&mut rng);
  321. let wg4 = Scalar::random(&mut rng);
  322. let zg5 = Scalar::random(&mut rng);
  323. let wg5 = Scalar::random(&mut rng);
  324. let zg6 = Scalar::random(&mut rng);
  325. let wg6 = Scalar::random(&mut rng);
  326. let zg7 = Scalar::random(&mut rng);
  327. let wg7 = Scalar::random(&mut rng);
  328. let zg8 = Scalar::random(&mut rng);
  329. let wg8 = Scalar::random(&mut rng);
  330. // Compute zg0 to cancel things out as
  331. // zg0 = -(zsince + 2*zg1 + 4*zg2 + 8*zg3 + 16*zg4 + 32*zg5 + 64*zg6 + 128*zg7 + 256*zg8)
  332. // but use Horner's method
  333. let zg0 = -(scalar_dbl(
  334. &(scalar_dbl(
  335. &(scalar_dbl(
  336. &(scalar_dbl(
  337. &(scalar_dbl(
  338. &(scalar_dbl(&(scalar_dbl(&(scalar_dbl(&zg8) + zg7)) + zg6)) + zg5),
  339. ) + zg4),
  340. ) + zg3),
  341. ) + zg2),
  342. ) + zg1),
  343. ) + zsince);
  344. let yg0 = wg0 + g0 * zg0;
  345. let yg1 = wg1 + g1 * zg1;
  346. let yg2 = wg2 + g2 * zg2;
  347. let yg3 = wg3 + g3 * zg3;
  348. let yg4 = wg4 + g4 * zg4;
  349. let yg5 = wg5 + g5 * zg5;
  350. let yg6 = wg6 + g6 * zg6;
  351. let yg7 = wg7 + g7 * zg7;
  352. let yg8 = wg8 + g8 * zg8;
  353. let CG0 = g0 * P + &zg0 * Atable;
  354. let CG1 = g1 * P + &zg1 * Atable;
  355. let CG2 = g2 * P + &zg2 * Atable;
  356. let CG3 = g3 * P + &zg3 * Atable;
  357. let CG4 = g4 * P + &zg4 * Atable;
  358. let CG5 = g5 * P + &zg5 * Atable;
  359. let CG6 = g6 * P + &zg6 * Atable;
  360. let CG7 = g7 * P + &zg7 * Atable;
  361. let CG8 = g8 * P + &zg8 * Atable;
  362. let CG0sq = g0 * P + &yg0 * Atable;
  363. let CG1sq = g1 * P + &yg1 * Atable;
  364. let CG2sq = g2 * P + &yg2 * Atable;
  365. let CG3sq = g3 * P + &yg3 * Atable;
  366. let CG4sq = g4 * P + &yg4 * Atable;
  367. let CG5sq = g5 * P + &yg5 * Atable;
  368. let CG6sq = g6 * P + &yg6 * Atable;
  369. let CG7sq = g7 * P + &yg7 * Atable;
  370. let CG8sq = g8 * P + &yg8 * Atable;
  371. // Construct the proof
  372. let mut transcript = Transcript::new(b"level upgrade request");
  373. let piUser = requestproof::prove_compact(
  374. &mut transcript,
  375. requestproof::ProveAssignments {
  376. A: &A,
  377. B: &B,
  378. P: &P,
  379. CBucket: &CBucket,
  380. CSince: &CSince,
  381. CInvRemain: &CInvRemain,
  382. CInvIssued: &CInvIssued,
  383. V: &V,
  384. Xbucket: &lox_pub.X[2],
  385. Xsince: &lox_pub.X[4],
  386. Xinvremain: &lox_pub.X[5],
  387. Xinvissued: &lox_pub.X[6],
  388. P_reach: &P_reach,
  389. CBucket_reach: &CBucket_reach,
  390. V_reach: &V_reach,
  391. Xbucket_reach: &reach_pub.X[2],
  392. D: &D,
  393. EncIdClient0: &EncIdClient.0,
  394. EncIdClient1: &EncIdClient.1,
  395. EncBucket0: &EncBucket.0,
  396. EncBucket1: &EncBucket.1,
  397. EncInvIssued0: &EncInvIssued.0,
  398. EncInvIssued1: &EncInvIssued.1,
  399. CG0: &CG0,
  400. CG1: &CG1,
  401. CG2: &CG2,
  402. CG3: &CG3,
  403. CG4: &CG4,
  404. CG5: &CG5,
  405. CG6: &CG6,
  406. CG7: &CG7,
  407. CG8: &CG8,
  408. CG0sq: &CG0sq,
  409. CG1sq: &CG1sq,
  410. CG2sq: &CG2sq,
  411. CG3sq: &CG3sq,
  412. CG4sq: &CG4sq,
  413. CG5sq: &CG5sq,
  414. CG6sq: &CG6sq,
  415. CG7sq: &CG7sq,
  416. CG8sq: &CG8sq,
  417. bucket: &lox_cred.bucket,
  418. since: &lox_cred.level_since,
  419. invremain: &lox_cred.invites_remaining,
  420. invissued: &lox_cred.invites_issued,
  421. zbucket: &zbucket,
  422. zsince: &zsince,
  423. zinvremain: &zinvremain,
  424. zinvissued: &zinvissued,
  425. negzQ: &negzQ,
  426. zbucket_reach: &zbucket_reach,
  427. negzQ_reach: &negzQ_reach,
  428. d: &d,
  429. eid_client: &eid_client,
  430. ebucket: &ebucket,
  431. einvissued: &einvissued,
  432. id_client: &id_client,
  433. g0: &g0,
  434. g1: &g1,
  435. g2: &g2,
  436. g3: &g3,
  437. g4: &g4,
  438. g5: &g5,
  439. g6: &g6,
  440. g7: &g7,
  441. g8: &g8,
  442. zg0: &zg0,
  443. zg1: &zg1,
  444. zg2: &zg2,
  445. zg3: &zg3,
  446. zg4: &zg4,
  447. zg5: &zg5,
  448. zg6: &zg6,
  449. zg7: &zg7,
  450. zg8: &zg8,
  451. wg0: &wg0,
  452. wg1: &wg1,
  453. wg2: &wg2,
  454. wg3: &wg3,
  455. wg4: &wg4,
  456. wg5: &wg5,
  457. wg6: &wg6,
  458. wg7: &wg7,
  459. wg8: &wg8,
  460. yg0: &yg0,
  461. yg1: &yg1,
  462. yg2: &yg2,
  463. yg3: &yg3,
  464. yg4: &yg4,
  465. yg5: &yg5,
  466. yg6: &yg6,
  467. yg7: &yg7,
  468. yg8: &yg8,
  469. },
  470. )
  471. .0;
  472. Ok((
  473. Request {
  474. P,
  475. id: lox_cred.id,
  476. CBucket,
  477. level: lox_cred.trust_level,
  478. CSince,
  479. CInvRemain,
  480. CInvIssued,
  481. CQ,
  482. P_reach,
  483. CBucket_reach,
  484. CQ_reach,
  485. D,
  486. EncIdClient,
  487. EncBucket,
  488. EncInvIssued,
  489. CG1,
  490. CG2,
  491. CG3,
  492. CG4,
  493. CG5,
  494. CG6,
  495. CG7,
  496. CG8,
  497. CG0sq,
  498. CG1sq,
  499. CG2sq,
  500. CG3sq,
  501. CG4sq,
  502. CG5sq,
  503. CG6sq,
  504. CG7sq,
  505. CG8sq,
  506. piUser,
  507. },
  508. State {
  509. d,
  510. D,
  511. EncIdClient,
  512. EncBucket,
  513. EncInvIssued,
  514. id_client,
  515. bucket: lox_cred.bucket,
  516. level: lox_cred.trust_level + Scalar::one(),
  517. invremain: newinvites,
  518. invissued: lox_cred.invites_issued,
  519. },
  520. ))
  521. }