profile
viewpoint
Oleg Andreev oleganza Protocol architect at Stellar Berlin oleganza.com

oleganza/CoreBitcoin 665

Awesome Bitcoin toolkit for ObjC and Swift

dalek-cryptography/bulletproofs 539

A pure-Rust implementation of Bulletproofs using Ristretto.

oleganza/bitcoin-papers 145

Personal ideas and inventions for Bitcoin

oleganza/btcruby 67

Comprehensive Bitcoin and Open Assets toolkit for Ruby

oleganza/bash-settings 41

My personal bash aliases and settings

bobg/scp 29

Standalone implementation of the Stellar Consensus Protocol.

oleganza/autogit 20

AutoGit is an automatic package manager for Ruby (alternative to RubyGems)

oleganza/ampoule 16

git-based todo manager/bugtracker

oleganza/bitcoin-duo 12

Bitcoin Duo: achieving consensus the safe way

oleganza/blindsignaturedemo 12

Bitcoin Blind Signatures Demo

push eventstellar/slingshot

Oleg Andreev

commit sha b196d7a6865a97f1e44ffde93e5924b0a97a4e0d

wip on node architecture

view details

push time in 9 days

issue commentdalek-cryptography/bulletproofs

Formal model for circuit randomization

I've looked at plookup paper (commentary) recently and it seems like it needs more than two phases that our API currently provides.

TL;DR of plookup

  1. make a map of valid inputs->outputs for a given bitwise function.
  2. compress each line via a challenge-based polynomial into a single scalar (that includes input and output bits) => {t_i}
  3. do the same for the actual wires at hand => {f_i}
  4. commit to a sorted list of the wires concatenated with lookup table {t} => {s_i} = sort(f || t).
  5. perform permutation check (aka "grand product check", aka shuffle gadget): Prod[(x-a_i)]==Prod[x-b_i] with these two vectors:

{a} = {s_i + β*s_(i+1)} // randomized difference between neighbours {b} = (1+β)f || {t_i + βt_(i+1)}

where β is an extra random challenge

so it yields 2(|f| + |t|) multipliers, while one-by-one membership check would take |f|*|t| multipliers

the idea behind concatenation is that you'll have each value from lookup table found at least once. So if your program used it K times, it'll be found K+1 times

and the randomized "difference" would mean that for K times there's a match, you'd find it in (1+β)f subvector, and for K+1st match it'd be at "transition" from one value to a different one, and would match with {t_i + βt_(i+1)} subvector

Why more phases?

  1. In phase 1: commit to individual wires
  2. In phase 2: sample a challenge to tuple-compress groups of wires into scalars for lookup and commit these values along with a sorted vector of them (sorted vector contains values computed with challenges).
  3. In phase 3: sample another pair of random challenges to perform final product check with "randomized difference vectors" (one challenge for randomized difference, another - for sampling polynomials for the shuffle gadget).
hdevalence

comment created time in 20 days

push eventstellar/slingshot

Oleg Andreev

commit sha 9b3091914a7dd82112a5fce2faa452ba440080ce

fix link linter

view details

push time in 21 days

push eventstellar/slingshot

Oleg Andreev

commit sha 7ed1ac5773f8ec7873b4ad6f0f941502b1c38f88

wip on API

view details

push time in 21 days

push eventstellar/slingshot

Oleg Andreev

commit sha fc8fb85b38e662cae72ca03c3e5b18c952a2a898

wip on wallet api

view details

push time in a month

PR opened stellar/slingshot

node: wip on spec
+215 -0

0 comment

1 changed file

pr created time in a month

create barnchstellar/slingshot

branch : oleg/api-spec.md

created branch time in a month

push eventstellar/slingshot

Oleg Andreev

commit sha c9c6aec231f0fcb4ad4215b485c4bb7b7bb51382

zkvm: rename CS variable operations (#487) Closes #482. * `const` -> `scalar` for instantiating clear-text scalar values * `var` -> `commit` for high-level variables tied to Pedersen commitments ("external facts") * unchanged: `alloc` for low-level variables not tied to any external commitments.

view details

push time in a month

PR merged stellar/slingshot

zkvm: rename CS variable operations

Closes #482.

  • const -> scalar for instantiating clear-text scalar values
  • var -> commit for high-level variables tied to Pedersen commitments ("external facts")
  • unchanged: alloc for low-level variables not tied to any external commitments.
+66 -63

0 comment

8 changed files

oleganza

pr closed time in a month

issue closedstellar/slingshot

zkvm: rename variable and constant operations

Problem

Current operation names const, var and alloc do not quite reflect what they are doing.

Proposal

One way to make these better, although I'm still looking for a better naming:

const -> scalar because it creates an expression with a clear-text scalar.

var -> const because it creates a r1cs "variable" out of a Pedersen commitment, which makes it a constant value in a sense.

alloc -> var because it create a true "variable" since the user can choose its value freely w/o being tied to any pre-existing commitments.

Why these are not good enough?

scalar name is close to perfect because it's what it literally does. But in the ZkVM spec it clashes with the section on the Scalar type, so we should probably rename it to "Scalar type" from simply "Scalar".

var/const is not quite the correct distinction since in the r1cs most "low level variables", although secret, often assigned very specific values to satisfy constrains and do not dynamically change as the execution or verification happens, like regular variables/registers in an actual computer.

closed time in a month

oleganza

push eventstellar/slingshot

Oleg Andreev

commit sha ff46866460366e2ccded17392f7d920b15428d86

schema fmt

view details

push time in a month

push eventstellar/slingshot

Oleg Andreev

commit sha cc1c24216505d6f135c2166925836744fce61616

fix

view details

push time in a month

PR opened stellar/slingshot

zkvm: rename CS variable operations

Closes #482.

  • const -> scalar for instantiating clear-text scalar values
  • var -> commit for high-level variables tied to Pedersen commitments ("external facts")
  • unchanged: alloc for low-level variables not tied to any external commitments.
+64 -61

0 comment

7 changed files

pr created time in a month

push eventstellar/slingshot

Oleg Andreev

commit sha 9275cfa30cc050bb653d52b660a20183240c1e18

fix

view details

push time in a month

push eventstellar/slingshot

Oleg Andreev

commit sha a31ad175ab75586375bf30018657b0f0d6b090fb

zkvm: rename var->commit

view details

push time in a month

push eventstellar/slingshot

Oleg Andreev

commit sha ae7218d349d043eda7d1cc4c48722f4f12e408da

zkvm: rename ops::const to ops::scalar

view details

push time in a month

create barnchstellar/slingshot

branch : oleg/zkvm-rename-ops

created branch time in a month

issue commentstellar/slingshot

zkvm: rename variable and constant operations

Another idea:

  • scalar for instantiating clear-text scalar values (was const)
  • commit for high-level variables tied to Pedersen commitments ("external facts")
  • alloc for low-level variables not tied to any external commitments.
oleganza

comment created time in a month

issue closedstellar/slingshot

node/wallet: utxo and tx state machine

Problem

I'm in process of porting the wallet logic from the ./demo crate to ./node/wallet module and want to make sure the logic of tracking UTXOs is correct. The version in the demo is not well-specified and looks more like a patchwork and does not work reliably with respect to unconfirmed (mempool'ed) transactions.

Definitions

Tx: a ZkVM transaction

Output: location of the value locked in a contract of a transaction that can be spent by an input in the child tx.

UTXO: unspent tx output.

Confirmed: presence in the blockchain.

Unconfirmed: absence in the blockchain, but possible presence in the mempool.

Address: a key controlled by this wallet, derived from a single "account xpub".

Incoming: other party's payment towards an address controlled by this wallet.

Outgoing: tx or output created by this wallet.

Change: an output that sends the rest of the value back to the wallet.

Requirements

  1. The wallet must provide a list of spendable utxos through its API that consist of:
    • confirmed incoming payments,
    • confirmed change outputs, and
    • unconfirmed change outputs,
    • excluding unconfirmed incoming payments, as the wallet has no control over the chance of those not being double-spent in the future.
  2. When the wallet makes a payment:
    • it needs to store the unconfirmed tx, so it will attempt to re-submit it to mempool whenever it falls out of it,
    • remember the change output, so it can be spent in the next payment,
    • remember the annotation for both the change and destination output, so this data can be rendered in the UI.
  3. When the wallet receives a payment:
    • a newly observed (confirmed or unconfirmed) tx is checked against the list of known addresses (stored or on-the-fly derived from account xpub) to detect whether this tx is relevant for this wallet,
    • confirmed outputs (change + incoming) that can be spent by the wallet are added as confirmed spendable utxos.
    • unconfirmed outputs and their transactions are treated separately:
      • outgoing transactions have their change outputs marked as spendable.
      • incoming transactions have their payment output counting towards unconfirmed balance, but not used for spending.
  4. When the wallet adds unconfirmed tx to the mempool:
    • if it fails to be added, it can only be because it's expired or double-spent: then associated outputs are removed from the balance. Note: this can only happen with incoming txs, as outgoing ones are never intentionally double-spent by the wallet (and the maxtime on wallet's txs is set to infinity).
  5. Wallet can expect that the notifications about txs, from blocks or from mempool are coming in correct topological order: meaning, children come after parents. Likewise, attempts to re-add unconfirmed txs to mempool must happen parent-first.
  6. Since the incoming unconfirmed txs can be double-spent by the originator, those outputs must not be used for outgoing payments, nor should be stored alongside confirmed outputs, so we properly evict them when we evict the transaction.

Design sketch

  • Single SQLite database for the wallet state.
  • accounts table that stores xpubs.
  • addresses table that stores derived addresses and account_id, with expiration date - incoming txs are matched against this table to find if they belong to any account.
  • incoming_txs: list of unconfirmed incoming txs, to be continuously re-added to mempool, or removed if they become invalid.
  • outgoing_txs: list of unconfirmed outgoing txs. Same treatment as for incoming, except we know that we are not going to double-spend these txs and can expect them to be confirmed some time in the future (if they are stuck with low-fees, CPFP strategy will allow bumping the fee).
  • pending_utxos: list of unconfirmed outputs that form an unconfirmed (and untrusted) balance. Linked to its tx via incoming_tx_id in the incoming_txs table.
  • confirmed_utxos: list of confirmed outputs that can be spent by the wallet. Does not contain unconfirmed outputs.
  • annotated_outputs table for UI purposes - contains every known output, whether incoming, outgoing or change. Used to display txs in the UI only, not used for calculating balances and spendable utxo subset.
  • annotated_txs - same as outputs, but for raw txs.

API sketch

  • add an account with xpub
  • get spendable utxos to compute balance
  • get unconfirmed incoming utxos to compute full pending unconfirmed balance
  • get a list of annotated txs for a given time period, or simply paginated.
  • feed new txs from blockchain or mempool, and absorb+annotate the relevant ones in appropriate DB tables.
  • query unconfirmed txs in topological order to add to mempool
  • remove unconfirmed incoming txs (when they are expired / conflicting - failed to be (re)added to the mempool)
  • generate a new address with expiration time
  • prune expired addresses

closed time in a month

oleganza

issue commentstellar/slingshot

node/wallet: utxo and tx state machine

Done in #473

oleganza

comment created time in a month

push eventstellar/slingshot

Oleg Andreev

commit sha 941a67f86fe4616b6abc684a1b526d2cacbfeb31

node: pseparate signing from building (#486)

view details

push time in a month

PR merged stellar/slingshot

node: separate signing from building

Adds intermediate type BuiltTx that contains all tx data, utreexo proofs, and signing instructions (derivation sequences and aliases). Then, the BuiltTx::sign method takes an Xprv, derives all the keys according to the instructions and returns a fully signed BlockTx, that can be published.

Closes #485

+80 -38

0 comment

3 changed files

oleganza

pr closed time in a month

issue closedstellar/slingshot

node/wallet: separate signing API from tx building

Currently we build tx and sign it with xprv in one go. We should optimize this process for external signing devices, so we can provide signing instructions and a short annotation of the tx, so the signer can see how much of which assets being signed off, so the user can confirm.

Follow up to #473.

closed time in a month

oleganza

PR opened stellar/slingshot

node: separate signing from building

Adds intermediate type BuiltTx that contains all tx data, utreexo proofs, and signing instructions (derivation sequences and aliases). Then, the BuiltTx::sign method takes an Xprv, derives all the keys according to the instructions and returns a fully signed BlockTx, that can be published.

Closes #485

+80 -38

0 comment

3 changed files

pr created time in a month

create barnchstellar/slingshot

branch : oleg/wallet-separate-signing

created branch time in a month

delete branch stellar/slingshot

delete branch : oleg/node-wallet

delete time in a month

issue openedstellar/slingshot

node/wallet: separate signing API from tx building

Currently we build tx and sign it with xprv in one go. We should optimize this process for external signing devices, so we can provide signing instructions and a short annotation of the tx, so the signer can see how much of which assets being signed off, so the user can confirm.

Follow up to #473.

created time in a month

issue openedstellar/slingshot

node: wallet RPC api

Make wallet data accessible from the RPC API (to query txs, balances, submit transactions).

Follow up to #473.

created time in a month

push eventstellar/slingshot

Oleg Andreev

commit sha ff87f48043b5f7842641554328868d3fb78170d0

node/wallet: new module for handling accounts and spendable utxos (#473)

view details

push time in a month

PR merged stellar/slingshot

node/wallet: new module for handling accounts and spendable utxos

This adds wallet logic. So we can manage spendable utxos.

Data model

The entire wallet data is a list of unexpired receivers, annotated txs and spendable utxos with different states.

For simplicity, we'll store the entire thing in a single file and load it as a whole. Later, we'll probably need to keep it in a sqlite or at least separate files: for pending txs, for spendable utxos, for archived txs, etc. Make sure the storage is completely separate from the blockchain data.

TODO

  • [x] init new blockchain with a new account "Main" that gets seed utxos.
  • [x] review block/tx processing logic to differentiate between detecting unconfirmed txs and confirmed txs
  • [x] make the wallet storable per config options
  • [x] issuance API
+1342 -183

0 comment

29 changed files

oleganza

pr closed time in a month

push eventstellar/slingshot

Oleg Andreev

commit sha b255845cff9a862c1962219854e26de4dc286116

wallet: remove unused func

view details

push time in a month

push eventstellar/slingshot

Oleg Andreev

commit sha 27c4aa4011e71343eca39d3df1ff13d18728fae5

full tx builder api

view details

push time in a month

push eventstellar/slingshot

Oleg Andreev

commit sha b980cd0aa8388a4a9d4d511b06246c5e849a0a8d

token: issuing key derivation API

view details

push time in a month

push eventstellar/slingshot

Oleg Andreev

commit sha 6c5bb06d612ae25f87ca1a4204101ae5e83ac249

cleanup

view details

push time in a month

push eventstellar/slingshot

Oleg Andreev

commit sha 198d4a6a5d2b26af40fa033894ed593314a7d8dc

wip on refactoring

view details

push time in a month

push eventstellar/slingshot

Oleg Andreev

commit sha 88aea4e758d4791f0eef60729b0d8825f5863e67

wip

view details

push time in a month

push eventstellar/slingshot

Oleg Andreev

commit sha a674658780b496215fd229eaff73ec951134064a

fmt

view details

push time in a month

push eventstellar/slingshot

Oleg Andreev

commit sha c34cc79f1583bc8325ab647dcea536ba24c600bf

API upd

view details

Oleg Andreev

commit sha ac774f35302b643958810a2a8a3c6572496fa9ca

wip on wallet logic

view details

push time in a month

push eventstellar/slingshot

Oleg Andreev

commit sha df14c8ee91931ea9c5755e0dd56cc6e949fc0e55

demo: \fix for api

view details

push time in a month

push eventstellar/slingshot

Oleg Andreev

commit sha 302b16521e159a771cc6e8716d3c439487867df7

upd tests after blockchain api change

view details

push time in a month

push eventstellar/slingshot

Oleg Andreev

commit sha 9ab7a337b4d6d6718f16eb26b48a37578333c5cc

refactored VerifiedBlock/Block workflow

view details

push time in a month

push eventstellar/slingshot

Oleg Andreev

commit sha 492e3e37e5900ee4452d0ec25d955c5db7be6e0e

api adjustments

view details

Oleg Andreev

commit sha 7f26dfb5a69f7c01de1ca21be33d76331633f841

fmt

view details

Oleg Andreev

commit sha 5defbd7ca3101515fbbb60797473cb8481453721

wallet api

view details

push time in a month

push eventstellar/slingshot

Oleg Andreev

commit sha b03fa80f7b3943bdcbbd209553f2d20da1adca8e

WIP WIP

view details

push time in a month

issue commentdalek-cryptography/bulletproofs

secp256k1 support

This should be possible in principle. BPs use arithmetic API for scalars and opaque group elements, plus a multiscalar multiplication API for efficient verification.

Implementation of multiscalar multiplication (see curve-25519-dalek impls) is more group-specific, as it relies on certain size and bit patterns in the scalars, plus various point representations on curve25519, switching from one to another based on whether a point is readded multiple times.

tarcieri

comment created time in 2 months

issue commentdalek-cryptography/bulletproofs

[Question] Why blinding vectors in range proof didn't use Transcript::build_rng()

As far as I understand, the current multi-party API makes it awkward to simply extrude RNG out of the main transcript: the transcript is owned by the Dealer, while blinding factors are generated in the Party.

If the goal is to mix the externally-provided blinding factors with the system RNG, then each Party may instantiate an auxiliary instance, throw in the externally provided blinding factors, then extrude an RNG and keep it around through all the subsequent states.

WDYT @cathieyun @hdevalence?

alxiong

comment created time in 2 months

push eventstellar/slingshot

Oleg Andreev

commit sha c9fab7222017f23af702f126b38f49bb2e43f9c4

address/receiver api revamp

view details

Oleg Andreev

commit sha becd7d58484c0920eaebdce7bcfaace2a08eeefb

wip on wallet state machine

view details

push time in 2 months

delete branch stellar/slingshot

delete branch : oleg/demo-fix-acc

delete time in 2 months

delete branch stellar/slingshot

delete branch : oleg/address

delete time in 2 months

issue openedstellar/slingshot

zkvm: support short encoding for scalars and integers

Problem

Currently const instruction expects a 32-byte canonically-encoded ristretto255 Scalar. This is suboptimal when we want to store small-range parameters such as timestamps (8 bytes) and sequence numbers (<4 bytes).

Proposal

Encode scalars with top all-zero bytes trimmed. To prevent malleability, require that encoding for all scalars.

  1. When encoding a scalar in a program: encode the scalar in a 32-byte string, trim all-zero bytes from the end of the 32-byte .
  2. When reading a scalar, check that top byte is not zero, then pad 32-byte array with zeroes before decoding it and checking if it's canonical.

Under this encoding:

  • number 0 is encoded as an empty string,
  • 1..255 as [01]..[ff],
  • 256..65535 as [00 01]..[ff ff] and so on.

Alternative

We could introduce a separate type "integer", that has fixed-length 8-byte encoding. This is still not optimal for small integers, and introduces an extra type and requires additional rules of conversion to scalars, and a separate instruction to read it.

created time in 3 months

issue openedstellar/slingshot

zkvm: rename variable and constant operations

Problem

Current operation names const, var and alloc do not quite reflect what they are doing.

Proposal

One way to make these better, although I'm still looking for a better naming:

const -> scalar because it creates an expression with a clear-text scalar.

var -> const because it creates a r1cs "variable" out of a Pedersen commitment, which makes it a constant value in a sense.

alloc -> var because it create a true "variable" since the user can choose its value freely w/o being tied to any pre-existing commitments.

Why these are not good enough?

scalar name is close to perfect because it's what it literally does. But in the ZkVM spec it clashes with the section on the Scalar type, so we should probably rename it to "Scalar type" from simply "Scalar".

var/const is not quite the correct distinction since in the r1cs most "low level variables", although secret, often assigned very specific values to satisfy constrains and do not dynamically change as the execution or verification happens, like regular variables/registers in an actual computer.

created time in 3 months

issue openedstellar/slingshot

zkvm: payment channel API

Here's a sketch of a simple payment channel.

Requirements

  1. Two parties agree to lock two values, one from each side, under a 2-of-2 multisig predicate. Quantities could be different, the flavors are the same. E.g. $10:$10, or $100:nothing.
  2. Before forming a transaction that locks the funds, they prepare a signed program (to be used with signtag instruction) that re-locks the values under their individual predicates, but allows withdrawal only after a fixed timeout (e.g. 24h) since the publication of the transaction that uses that program.
  3. To update the balances, they mutually sign a new signed program that re-locks values in different proportions.
  4. During the timeout, a later-signed program can be used to update the state of the contract. This is important to ensure that counterparty cannot publish and withdraw money that was already spent.
  5. When parties are done exchanging balances, they cooperatively sign a transaction that unlocks the value in required proportion, without ever using signed programs, that were needed as a security measure. This makes transactions that open and close the channel indistinguishable from a plain payment.

Design

States of the channel

  1. Nil: funds belong to their owners, the channel is not created yet.
  2. Ready(n): funds are locked at state N (=0,1,2,3,...).
  3. Closing: funds are time-locked before they can be released to the owners.
  4. Final: funds are returned to the owners in a new proportion.

Transitions

Nil->Ready: transaction with two inputs, and3 outputs: one output containing values locked in the channel under predicate P, the other two containing change quantities that return back to the users.

Ready->Final: transaction that's mutually signed by both parties that locks the values under predicates chosen by the parties. This may also be used to "top up" the existing channel using a single transaction (that moves funds from the old channel to a new one, possibly with additional funds injected).

Ready->Closing(0): a signed predicate is used in a transaction that moves the funds from the idle state to a state of a time-lock before the values can be withdrawn. Assets are locked under predicate C(0).

Closing(m)->Closing(n): a signed predicate is used to "bump" the state of the contract to a more up-to-date balance distribution (contract verifies that n > m). Assets are locked under new predicate C(n).

Closing(n)->Final: after a timeout, the user can form a transaction that unlocks the funds into two predicates, per specified distribution, one value per party.

Predicates

P: a Taproot predicate with a signing key defined as 2-of-2 musig aggregated key belonging to the parties and a program. TBD: specify how this program is compatible with signed programs.

C(n): a Taproot predicate with the same 2-of-2 key, with a clause that allows withdrawal after timeout.

TBD: specify the keys set up by both parties.

TBD: specify the logic of the signed program.

created time in 3 months

more