Skip to content

Commit

Permalink
Merge pull request dusk-network#3 from dusk-network/rangeproof-encoding
Browse files Browse the repository at this point in the history
Port rangeproof to dusk-crypto from dusk-blockchain
  • Loading branch information
autholykos committed Aug 17, 2019
2 parents 3c4db22 + d136bbc commit 1c3dd16
Show file tree
Hide file tree
Showing 11 changed files with 443 additions and 54 deletions.
1 change: 0 additions & 1 deletion rangeproof/bitCommitment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"testing"

"github.com/dusk-network/dusk-crypto/rangeproof"

"github.com/stretchr/testify/assert"
)

Expand Down
3 changes: 1 addition & 2 deletions rangeproof/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ import (

"github.com/pkg/errors"

"github.com/dusk-network/dusk-crypto/rangeproof/vector"

ristretto "github.com/bwesterb/go-ristretto"
"github.com/dusk-network/dusk-crypto/rangeproof/vector"

"github.com/dusk-network/dusk-crypto/rangeproof/pedersen"
)
Expand Down
2 changes: 1 addition & 1 deletion rangeproof/generators/generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import (
"testing"

ristretto "github.com/bwesterb/go-ristretto"
"github.com/stretchr/testify/assert"
generator "github.com/dusk-network/dusk-crypto/rangeproof/generators"
"github.com/stretchr/testify/assert"
)

func TestGeneratorsLen(t *testing.T) {
Expand Down
113 changes: 111 additions & 2 deletions rangeproof/innerproduct/innerproduct.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package innerproduct

import (
"bytes"
"encoding/binary"
"errors"
"io"
"math/bits"

ristretto "github.com/bwesterb/go-ristretto"
"github.com/dusk-network/dusk-crypto/rangeproof/fiatshamir"
"github.com/dusk-network/dusk-crypto/rangeproof/vector"

ristretto "github.com/bwesterb/go-ristretto"
)

// This is a reference of the innerProduct implementation at rust
Expand All @@ -23,6 +25,8 @@ type Proof struct {
func Generate(GVec, HVec []ristretto.Point, aVec, bVec, HprimeFactors []ristretto.Scalar, Q ristretto.Point) (*Proof, error) {
n := uint32(len(GVec))

// XXX : When n is not a power of two, will the bulletproof struct pad it
// or will the inner product proof struct?
if !isPower2(uint32(n)) {
return nil, errors.New("[IPProof]: size of n (NM) is not a power of 2")
}
Expand Down Expand Up @@ -386,6 +390,105 @@ func (proof *Proof) Verify(G, H, L, R []ristretto.Point, HprimeFactor []ristrett
return have.Equals(&P)
}

func (p *Proof) Encode(w io.Writer) error {

err := binary.Write(w, binary.BigEndian, p.A.Bytes())
if err != nil {
return err
}
err = binary.Write(w, binary.BigEndian, p.B.Bytes())
if err != nil {
return err
}
lenL := uint32(len(p.L))

for i := uint32(0); i < lenL; i++ {
err = binary.Write(w, binary.BigEndian, p.L[i].Bytes())
if err != nil {
return err
}
err = binary.Write(w, binary.BigEndian, p.R[i].Bytes())
if err != nil {
return err
}
}
return nil
}

func (p *Proof) Decode(r io.Reader) error {
if p == nil {
return errors.New("struct is nil")
}

var ABytes, BBytes [32]byte
err := binary.Read(r, binary.BigEndian, &ABytes)
if err != nil {
return err
}
err = binary.Read(r, binary.BigEndian, &BBytes)
if err != nil {
return err
}
p.A.SetBytes(&ABytes)
p.B.SetBytes(&BBytes)

buf := &bytes.Buffer{}
_, err = buf.ReadFrom(r)
if err != nil {
return err
}
numBytes := len(buf.Bytes())
if numBytes%32 != 0 {
return errors.New("proof was not formatted correctly")
}
lenL := uint32(numBytes / 64)

p.L = make([]ristretto.Point, lenL)
p.R = make([]ristretto.Point, lenL)

for i := uint32(0); i < lenL; i++ {
var LBytes, RBytes [32]byte
err = binary.Read(buf, binary.BigEndian, &LBytes)
if err != nil {
return err
}
err = binary.Read(buf, binary.BigEndian, &RBytes)
if err != nil {
return err
}
p.L[i].SetBytes(&LBytes)
p.R[i].SetBytes(&RBytes)
}

return nil
}

func (p *Proof) Equals(other Proof) bool {
ok := p.A.Equals(&other.A)
if !ok {
return ok
}

ok = p.B.Equals(&other.B)
if !ok {
return ok
}

for i := range p.L {
ok := p.L[i].Equals(&other.L[i])
if !ok {
return ok
}

ok = p.R[i].Equals(&other.R[i])
if !ok {
return ok
}
}

return ok
}

func nextPow2(n uint) uint {
n--
n |= n >> 1
Expand All @@ -399,3 +502,9 @@ func nextPow2(n uint) uint {
func isPower2(n uint32) bool {
return (n & (n - 1)) == 0
}

func DiffNextPow2(n uint32) uint32 {
pow2 := nextPow2(uint(n))
padAmount := uint32(pow2) - n + 1
return padAmount
}
17 changes: 14 additions & 3 deletions rangeproof/innerproduct/innerproduct_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package innerproduct

import (
"bytes"
"testing"

ristretto "github.com/bwesterb/go-ristretto"
"github.com/dusk-network/dusk-crypto/rangeproof/pedersen"
"github.com/dusk-network/dusk-crypto/rangeproof/vector"

ristretto "github.com/bwesterb/go-ristretto"
"github.com/stretchr/testify/assert"
)

Expand All @@ -22,7 +22,18 @@ func TestProofCreation(t *testing.T) {
assert.Equal(t, nil, err)

ok := proof.Verify(G, H, proof.L, proof.R, Hpf, Q, P, int(n))
assert.Equal(t, true, ok)
assert.True(t, ok)

buf := &bytes.Buffer{}

err = proof.Encode(buf)
assert.Equal(t, nil, err)

var decodedProof Proof
decodedProof.Decode(buf)
assert.Equal(t, nil, err)
ok = proof.Equals(decodedProof)
assert.True(t, ok)

n = n * 2
}
Expand Down
73 changes: 70 additions & 3 deletions rangeproof/pedersen/pedersen.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package pedersen

import (
generator "github.com/dusk-network/dusk-crypto/rangeproof/generators"
"encoding/binary"
"errors"
"io"

ristretto "github.com/bwesterb/go-ristretto"
generator "github.com/dusk-network/dusk-crypto/rangeproof/generators"
)

// Pedersen represents a pedersen struct which holds
Expand All @@ -25,8 +28,8 @@ func New(genData []byte) *Pedersen {
var blindPoint ristretto.Point
var basePoint ristretto.Point

blindPoint.Derive([]byte("blindPoint"))
basePoint.SetBase()
basePoint.Derive([]byte("blindPoint"))
blindPoint.SetBase()

return &Pedersen{
BaseVector: gen,
Expand All @@ -46,6 +49,70 @@ type Commitment struct {
BlindingFactor ristretto.Scalar
}

func (c *Commitment) Encode(w io.Writer) error {
return binary.Write(w, binary.BigEndian, c.Value.Bytes())
}

func EncodeCommitments(w io.Writer, comms []Commitment) error {
lenV := uint32(len(comms))
err := binary.Write(w, binary.BigEndian, lenV)
if err != nil {
return err
}
for i := range comms {
err := comms[i].Encode(w)
if err != nil {
return err
}
}
return nil
}

func (c *Commitment) Decode(r io.Reader) error {
if c == nil {
return errors.New("struct is nil")
}

var cBytes [32]byte
err := binary.Read(r, binary.BigEndian, &cBytes)
if err != nil {
return err
}
ok := c.Value.SetBytes(&cBytes)
if !ok {
return errors.New("could not set bytes for commitment, not an encodable point")
}
return nil
}

func DecodeCommitments(r io.Reader) ([]Commitment, error) {

var lenV uint32
err := binary.Read(r, binary.BigEndian, &lenV)
if err != nil {
return nil, err
}

comms := make([]Commitment, lenV)

for i := uint32(0); i < lenV; i++ {
err := comms[i].Decode(r)
if err != nil {
return nil, err
}
}

return comms, nil
}

func (c *Commitment) EqualValue(other Commitment) bool {
return c.Value.Equals(&other.Value)
}

func (c *Commitment) Equals(other Commitment) bool {
return c.EqualValue(other) && c.BlindingFactor.Equals(&other.BlindingFactor)
}

func (p *Pedersen) commitToScalars(blind *ristretto.Scalar, scalars ...ristretto.Scalar) ristretto.Point {

n := len(scalars)
Expand Down
24 changes: 22 additions & 2 deletions rangeproof/pedersen/pedersen_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package pedersen_test

import (
"bytes"
"math/big"
"testing"

"github.com/dusk-network/dusk-crypto/rangeproof/pedersen"

ristretto "github.com/bwesterb/go-ristretto"
"github.com/dusk-network/dusk-crypto/rangeproof/pedersen"
"github.com/stretchr/testify/assert"
)

Expand All @@ -22,6 +22,26 @@ func TestPedersenScalar(t *testing.T) {

}

func TestEncodeDecode(t *testing.T) {
s := ristretto.Scalar{}
s.Rand()

c := pedersen.New([]byte("rand")).CommitToScalar(s)
assert.True(t, c.Equals(c))

buf := &bytes.Buffer{}
err := c.Encode(buf)
assert.Nil(t, err)

var decC pedersen.Commitment
err = decC.Decode(buf)
assert.Nil(t, err)

ok := decC.EqualValue(c)
assert.True(t, ok)

}

func TestPedersenVector(t *testing.T) {
ped := pedersen.New([]byte("some data"))
// ped.BaseVector.Compute(4) // since values are not precomputed, we will compute two of them here
Expand Down
5 changes: 3 additions & 2 deletions rangeproof/poly.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ import (

"github.com/pkg/errors"

"github.com/dusk-network/dusk-crypto/rangeproof/vector"

ristretto "github.com/bwesterb/go-ristretto"
"github.com/dusk-network/dusk-crypto/rangeproof/vector"
)

// Polynomial construction
Expand Down Expand Up @@ -155,6 +154,8 @@ func (p *polynomial) computeT0(y, z ristretto.Scalar, v []ristretto.Scalar, n, m

// calculates sum( z^(1+j) * ( 0^(j-1)n || 2 ^n || 0^(m-j)n ) ) from j = 1 to j=M (71)
// implementation taken directly from java implementation.
// XXX: Look into ways to speed this up, and improve readability
// XXX: pass n and m as parameters
func sumZMTwoN(z ristretto.Scalar) []ristretto.Scalar {

res := make([]ristretto.Scalar, N*M)
Expand Down
Loading

0 comments on commit 1c3dd16

Please sign in to comment.