// TODO swap return value order, remove GroupElement argument // expect nonce provider instead of WasabiRandom? public static (Knowledge knowledge, IEnumerable <GroupElement> bitCommitments) RangeProof(Scalar a, Scalar r, int width, WasabiRandom rnd) { var ma = a * Generators.Gg + r * Generators.Gh; var bits = Enumerable.Range(0, width).Select(i => a.GetBits(i, 1) == 0 ? Scalar.Zero : Scalar.One); // Generate bit commitments. // FIXME // - derive r_i from a, r, and additional randomness (like synthetic nonces)? // - maybe derive without randomness for idempotent requests? // (deterministic blinding terms)? probably simpler to just save // randomly generated credentials in memory or persistent storage, and // re-request by loading and re-sending. // - long term fee credentials will definitely need deterministic // randomness because the server can only give idempotent responses with // its own records. var randomness = Enumerable.Repeat(0, width).Select(_ => rnd.GetScalar()).ToArray(); var bitCommitments = bits.Zip(randomness, (b, r) => b * Generators.Gg + r * Generators.Gh); var columns = width * 3 + 1; // three witness terms per bit and one for the commitment
// TODO swap return value order, remove GroupElement argument // expect nonce provider instead of WasabiRandom? public static (Knowledge knowledge, IEnumerable <GroupElement> bitCommitments) RangeProof(Scalar a, Scalar r, int width, WasabiRandom rnd) { var ma = a * Generators.Gg + r * Generators.Gh; var bits = Enumerable.Range(0, width).Select(i => a.GetBits(i, 1) == 0 ? Scalar.Zero : Scalar.One); // Generate bit commitments. // FIXME // - derive r_i from a, r, and additional randomness (like synthetic nonces)? // - maybe derive without randomness for idempotent requests? // (deterministic blinding terms)? probably simpler to just save // randomly generated credentials in memory or persistent storage, and // re-request by loading and re-sending. // - long term fee credentials will definitely need deterministic // randomness because the server can only give idempotent responses with // its own records. var randomness = Enumerable.Repeat(0, width).Select(_ => rnd.GetScalar()).ToArray(); var bitCommitments = bits.Zip(randomness, (b, r) => b * Generators.Gg + r * Generators.Gh); var columns = width * 3 + 1; // three witness terms per bit and one for the commitment int bitColumn(int i) => 3 * i + 1; int rndColumn(int i) => bitColumn(i) + 1; int productColumn(int i) => bitColumn(i) + 2; // Construct witness vector. First term is r from Ma = a*Gg + r*Gh. This // is followed by 3 witness terms per bit commitment, the bit b_i, the // randomness in its bit commitment r_i, and their product rb_i (0 or r). var witness = new Scalar[columns]; witness[0] = r; foreach ((Scalar b_i, Scalar r_i, int i) in bits.Zip(randomness, Enumerable.Range(0, width), (x, y, z) => (x, y, z))) { witness[bitColumn(i)] = b_i; witness[rndColumn(i)] = r_i; witness[productColumn(i)] = r_i * b_i; } return(new Knowledge(RangeProof(ma, bitCommitments), new ScalarVector(witness)), bitCommitments); }
public CredentialIssuerSecretKey(WasabiRandom rng) : this(rng.GetScalar(), rng.GetScalar(), rng.GetScalar(), rng.GetScalar(), rng.GetScalar()) { }
public CoordinatorSecretKey(WasabiRandom rng) : this(rng.GetScalar(), rng.GetScalar(), rng.GetScalar(), rng.GetScalar(), rng.GetScalar()) { }