mirror of
https://github.com/vocdoni/arbo.git
synced 2026-01-08 21:37:57 -05:00
feature: mimc bls12 377 (#31)
add mimc hash implementation over bls12_377 ecc from gnark
This commit is contained in:
6
.github/workflows/circomtest.yml
vendored
6
.github/workflows/circomtest.yml
vendored
@@ -8,13 +8,13 @@ jobs:
|
|||||||
node-version: [16.x]
|
node-version: [16.x]
|
||||||
go-version: [1.23.x]
|
go-version: [1.23.x]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
- name: Use Node.js ${{ matrix.node-version }}
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v1
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.go-version }}
|
go-version: ${{ matrix.go-version }}
|
||||||
- name: run circom tests
|
- name: run circom tests
|
||||||
|
|||||||
29
.github/workflows/lint.yml
vendored
29
.github/workflows/lint.yml
vendored
@@ -2,15 +2,24 @@ name: Lint
|
|||||||
on: [ push, pull_request ]
|
on: [ push, pull_request ]
|
||||||
jobs:
|
jobs:
|
||||||
lint:
|
lint:
|
||||||
runs-on: ubuntu-latest
|
strategy:
|
||||||
|
matrix:
|
||||||
|
go-version: [1.23.x]
|
||||||
|
platform: [ubuntu-latest]
|
||||||
|
runs-on: ${{ matrix.platform }}
|
||||||
steps:
|
steps:
|
||||||
- name: Install Go
|
|
||||||
uses: actions/setup-go@v1
|
|
||||||
with:
|
|
||||||
go-version: 1.23.x
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
- name: Lint
|
- name: Install Go
|
||||||
run: |
|
uses: actions/setup-go@v5
|
||||||
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.30.0
|
with:
|
||||||
$(go env GOPATH)/bin/golangci-lint run --timeout=5m -c .golangci.yml
|
go-version: ${{ matrix.go-version }}
|
||||||
|
cache: true
|
||||||
|
- name: Run golangci-lint
|
||||||
|
uses: golangci/golangci-lint-action@v3
|
||||||
|
with:
|
||||||
|
version: latest
|
||||||
|
skip-cache: false
|
||||||
|
skip-pkg-cache: false
|
||||||
|
skip-build-cache: false
|
||||||
|
only-new-issues: true
|
||||||
|
|||||||
7
.github/workflows/test.yml
vendored
7
.github/workflows/test.yml
vendored
@@ -9,11 +9,12 @@ jobs:
|
|||||||
platform: [ubuntu-latest]
|
platform: [ubuntu-latest]
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
steps:
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v1
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.go-version }}
|
go-version: ${{ matrix.go-version }}
|
||||||
- name: Checkout code
|
cache: true
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: go test ./...
|
run: go test ./...
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
issues:
|
|
||||||
max-same-issues: 0
|
|
||||||
exclude-use-default: false
|
|
||||||
linters:
|
|
||||||
enable:
|
|
||||||
- whitespace
|
|
||||||
- gosec
|
|
||||||
- gci
|
|
||||||
- misspell
|
|
||||||
- gomnd
|
|
||||||
- gofmt
|
|
||||||
- goimports
|
|
||||||
- lll
|
|
||||||
- golint
|
|
||||||
- gocyclo
|
|
||||||
linters-settings:
|
|
||||||
lll:
|
|
||||||
line-length: 100
|
|
||||||
4
dbg.go
4
dbg.go
@@ -28,7 +28,7 @@ func (d *dbgStats) incHash() {
|
|||||||
d.hash++
|
d.hash++
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:unused
|
//nolint:all
|
||||||
func (d *dbgStats) incDbGet() {
|
func (d *dbgStats) incDbGet() {
|
||||||
if d == nil {
|
if d == nil {
|
||||||
return
|
return
|
||||||
@@ -36,7 +36,7 @@ func (d *dbgStats) incDbGet() {
|
|||||||
d.dbGet++
|
d.dbGet++
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:unused
|
//nolint:all
|
||||||
func (d *dbgStats) incDbPut() {
|
func (d *dbgStats) incDbPut() {
|
||||||
if d == nil {
|
if d == nil {
|
||||||
return
|
return
|
||||||
|
|||||||
22
ff.go
Normal file
22
ff.go
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package arbo
|
||||||
|
|
||||||
|
import "math/big"
|
||||||
|
|
||||||
|
var (
|
||||||
|
// BN254BaseField is the base field for the BN254 curve.
|
||||||
|
BN254BaseField, _ = new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
|
||||||
|
// BLS12377BaseField is the base field for the BLS12377 curve.
|
||||||
|
BLS12377BaseField, _ = new(big.Int).SetString("25825498262808887005865186224201665565126143020923472090132963926938185026661", 10)
|
||||||
|
)
|
||||||
|
|
||||||
|
// BigToFF function returns the finite field representation of the big.Int
|
||||||
|
// provided. It uses the curve scalar field to represent the provided number.
|
||||||
|
func BigToFF(baseField, iv *big.Int) *big.Int {
|
||||||
|
z := big.NewInt(0)
|
||||||
|
if c := iv.Cmp(baseField); c == 0 {
|
||||||
|
return z
|
||||||
|
} else if c != 1 && iv.Cmp(z) != -1 {
|
||||||
|
return iv
|
||||||
|
}
|
||||||
|
return z.Mod(iv, baseField)
|
||||||
|
}
|
||||||
28
ff_test.go
Normal file
28
ff_test.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package arbo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBigToFF(t *testing.T) {
|
||||||
|
baseField := BN254BaseField
|
||||||
|
iv := new(big.Int).Sub(baseField, big.NewInt(1))
|
||||||
|
// test with iv < baseField (the result should be iv)
|
||||||
|
z := BigToFF(baseField, iv)
|
||||||
|
if z.Cmp(iv) != 0 {
|
||||||
|
t.Fatalf("BigToFF failed: %v != %v", z, iv)
|
||||||
|
}
|
||||||
|
// test with iv > baseField (the result should be iv % baseField)
|
||||||
|
iv = new(big.Int).Add(baseField, big.NewInt(1))
|
||||||
|
z = BigToFF(baseField, iv)
|
||||||
|
if z.Cmp(big.NewInt(1)) != 0 {
|
||||||
|
t.Fatalf("BigToFF failed: %v != 0", z)
|
||||||
|
}
|
||||||
|
// test with iv == baseField (the result should be 0)
|
||||||
|
iv = baseField
|
||||||
|
z = BigToFF(baseField, iv)
|
||||||
|
if z.Cmp(big.NewInt(0)) != 0 {
|
||||||
|
t.Fatalf("BigToFF failed: %v != 0", z)
|
||||||
|
}
|
||||||
|
}
|
||||||
5
go.mod
5
go.mod
@@ -14,6 +14,7 @@ require (
|
|||||||
require (
|
require (
|
||||||
github.com/DataDog/zstd v1.5.2 // indirect
|
github.com/DataDog/zstd v1.5.2 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
|
github.com/bits-and-blooms/bitset v1.14.2 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/cockroachdb/errors v1.11.3 // indirect
|
github.com/cockroachdb/errors v1.11.3 // indirect
|
||||||
github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect
|
github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect
|
||||||
@@ -21,6 +22,8 @@ require (
|
|||||||
github.com/cockroachdb/pebble v1.1.2 // indirect
|
github.com/cockroachdb/pebble v1.1.2 // indirect
|
||||||
github.com/cockroachdb/redact v1.1.5 // indirect
|
github.com/cockroachdb/redact v1.1.5 // indirect
|
||||||
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
|
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
|
||||||
|
github.com/consensys/bavard v0.1.13 // indirect
|
||||||
|
github.com/consensys/gnark-crypto v0.14.0 // indirect
|
||||||
github.com/getsentry/sentry-go v0.27.0 // indirect
|
github.com/getsentry/sentry-go v0.27.0 // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
|
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
|
||||||
@@ -28,6 +31,7 @@ require (
|
|||||||
github.com/klauspost/compress v1.17.9 // indirect
|
github.com/klauspost/compress v1.17.9 // indirect
|
||||||
github.com/kr/pretty v0.3.1 // indirect
|
github.com/kr/pretty v0.3.1 // indirect
|
||||||
github.com/kr/text v0.2.0 // indirect
|
github.com/kr/text v0.2.0 // indirect
|
||||||
|
github.com/mmcloughlin/addchain v0.4.0 // indirect
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/prometheus/client_golang v1.19.1 // indirect
|
github.com/prometheus/client_golang v1.19.1 // indirect
|
||||||
@@ -39,4 +43,5 @@ require (
|
|||||||
golang.org/x/sys v0.26.0 // indirect
|
golang.org/x/sys v0.26.0 // indirect
|
||||||
golang.org/x/text v0.19.0 // indirect
|
golang.org/x/text v0.19.0 // indirect
|
||||||
google.golang.org/protobuf v1.34.2 // indirect
|
google.golang.org/protobuf v1.34.2 // indirect
|
||||||
|
rsc.io/tmplfunc v0.0.3 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
12
go.sum
12
go.sum
@@ -2,6 +2,8 @@ github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8=
|
|||||||
github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
|
github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
|
github.com/bits-and-blooms/bitset v1.14.2 h1:YXVoyPndbdvcEVcseEovVfp0qjJp7S+i5+xgp/Nfbdc=
|
||||||
|
github.com/bits-and-blooms/bitset v1.14.2/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4=
|
github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4=
|
||||||
@@ -18,6 +20,10 @@ github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwP
|
|||||||
github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
|
github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
|
||||||
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo=
|
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo=
|
||||||
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ=
|
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ=
|
||||||
|
github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ=
|
||||||
|
github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI=
|
||||||
|
github.com/consensys/gnark-crypto v0.14.0 h1:DDBdl4HaBtdQsq/wfMwJvZNE80sHidrK3Nfrefatm0E=
|
||||||
|
github.com/consensys/gnark-crypto v0.14.0/go.mod h1:CU4UijNPsHawiVGNxe9co07FkzCeWHHrb1li/n1XoU0=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@@ -34,6 +40,7 @@ github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg
|
|||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
|
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||||
github.com/iden3/go-iden3-crypto v0.0.17 h1:NdkceRLJo/pI4UpcjVah4lN/a3yzxRUGXqxbWcYh9mY=
|
github.com/iden3/go-iden3-crypto v0.0.17 h1:NdkceRLJo/pI4UpcjVah4lN/a3yzxRUGXqxbWcYh9mY=
|
||||||
github.com/iden3/go-iden3-crypto v0.0.17/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E=
|
github.com/iden3/go-iden3-crypto v0.0.17/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E=
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||||
@@ -46,6 +53,9 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
|||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
|
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
|
||||||
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
|
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
|
||||||
|
github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY=
|
||||||
|
github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU=
|
||||||
|
github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
|
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
|
||||||
@@ -111,3 +121,5 @@ google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6h
|
|||||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU=
|
||||||
|
rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA=
|
||||||
|
|||||||
34
hash.go
34
hash.go
@@ -4,6 +4,7 @@ import (
|
|||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/consensys/gnark-crypto/ecc/bls12-377/fr/mimc"
|
||||||
"github.com/iden3/go-iden3-crypto/poseidon"
|
"github.com/iden3/go-iden3-crypto/poseidon"
|
||||||
"golang.org/x/crypto/blake2b"
|
"golang.org/x/crypto/blake2b"
|
||||||
)
|
)
|
||||||
@@ -16,6 +17,9 @@ var (
|
|||||||
TypeHashPoseidon = []byte("poseidon")
|
TypeHashPoseidon = []byte("poseidon")
|
||||||
// TypeHashBlake2b represents the label for the HashFunction of Blake2b
|
// TypeHashBlake2b represents the label for the HashFunction of Blake2b
|
||||||
TypeHashBlake2b = []byte("blake2b")
|
TypeHashBlake2b = []byte("blake2b")
|
||||||
|
// TypeHashMiMC_BLS12_377 represents the label for the HashFunction of MiMC
|
||||||
|
// over BLS12-377 curve
|
||||||
|
TypeHashMiMC_BLS12_377 = []byte("mimc_bls12_377")
|
||||||
|
|
||||||
// HashFunctionSha256 contains the HashSha256 struct which implements
|
// HashFunctionSha256 contains the HashSha256 struct which implements
|
||||||
// the HashFunction interface
|
// the HashFunction interface
|
||||||
@@ -26,6 +30,9 @@ var (
|
|||||||
// HashFunctionBlake2b contains the HashBlake2b struct which implements
|
// HashFunctionBlake2b contains the HashBlake2b struct which implements
|
||||||
// the HashFunction interface
|
// the HashFunction interface
|
||||||
HashFunctionBlake2b HashBlake2b
|
HashFunctionBlake2b HashBlake2b
|
||||||
|
// HashFunctionMiMC_BLS12_377 contains the HashMiMC_BLS12_377 struct which
|
||||||
|
// implements the HashFunction interface
|
||||||
|
HashFunctionMiMC_BLS12_377 HashMiMC_BLS12_377
|
||||||
)
|
)
|
||||||
|
|
||||||
// Once Generics are at Go, this will be updated (August 2021
|
// Once Generics are at Go, this will be updated (August 2021
|
||||||
@@ -37,8 +44,6 @@ type HashFunction interface {
|
|||||||
Type() []byte
|
Type() []byte
|
||||||
Len() int
|
Len() int
|
||||||
Hash(...[]byte) ([]byte, error)
|
Hash(...[]byte) ([]byte, error)
|
||||||
// CheckInput checks if the input is valid without computing the hash
|
|
||||||
// CheckInput(...[]byte) error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// HashSha256 implements the HashFunction interface for the Sha256 hash
|
// HashSha256 implements the HashFunction interface for the Sha256 hash
|
||||||
@@ -120,3 +125,28 @@ func (f HashBlake2b) Hash(b ...[]byte) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
return hasher.Sum(nil), nil
|
return hasher.Sum(nil), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HashMiMC_BLS12_377 implements the HashFunction interface for the MiMC hash
|
||||||
|
// over the BLS12-377 curve
|
||||||
|
type HashMiMC_BLS12_377 struct{}
|
||||||
|
|
||||||
|
// Type returns the type of HashFunction for the HashMiMC_BLS12_377
|
||||||
|
func (f HashMiMC_BLS12_377) Type() []byte {
|
||||||
|
return TypeHashMiMC_BLS12_377
|
||||||
|
}
|
||||||
|
|
||||||
|
// Len returns the length of the Hash output for the HashMiMC_BLS12_377
|
||||||
|
func (f HashMiMC_BLS12_377) Len() int {
|
||||||
|
return mimc.BlockSize
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hash implements the hash method for the HashFunction HashMiMC_BLS12_377
|
||||||
|
func (f HashMiMC_BLS12_377) Hash(b ...[]byte) ([]byte, error) {
|
||||||
|
h := mimc.NewMiMC()
|
||||||
|
for i := 0; i < len(b); i++ {
|
||||||
|
if _, err := h.Write(SwapEndianness(b[i])); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SwapEndianness(h.Sum(nil)), nil
|
||||||
|
}
|
||||||
|
|||||||
14
hash_test.go
14
hash_test.go
@@ -53,3 +53,17 @@ func TestHashBlake2b(t *testing.T) {
|
|||||||
qt.Equals,
|
qt.Equals,
|
||||||
"928b20366943e2afd11ebc0eae2e53a93bf177a4fcf35bcc64d503704e65e202")
|
"928b20366943e2afd11ebc0eae2e53a93bf177a4fcf35bcc64d503704e65e202")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHashMiMC(t *testing.T) {
|
||||||
|
// MiMC hash
|
||||||
|
HashFunction := &HashMiMC_BLS12_377{}
|
||||||
|
b := []byte("test")
|
||||||
|
h, err := HashFunction.Hash(b)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
c := qt.New(t)
|
||||||
|
c.Assert(hex.EncodeToString(h),
|
||||||
|
qt.Equals,
|
||||||
|
"f881f34991492d823e02565c778b824bac5eacef6340b70ee90a8966a2e63900")
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package arbo
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@@ -41,13 +40,13 @@ func checkRoots(c *qt.C, tree1, tree2 *Tree) {
|
|||||||
func storeTree(c *qt.C, tree *Tree, path string) {
|
func storeTree(c *qt.C, tree *Tree, path string) {
|
||||||
dump, err := tree.Dump(nil)
|
dump, err := tree.Dump(nil)
|
||||||
c.Assert(err, qt.IsNil)
|
c.Assert(err, qt.IsNil)
|
||||||
err = ioutil.WriteFile(path+"-"+time.Now().String()+".debug", dump, 0600)
|
err = os.WriteFile(path+"-"+time.Now().String()+".debug", dump, 0600)
|
||||||
c.Assert(err, qt.IsNil)
|
c.Assert(err, qt.IsNil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint:unused
|
// nolint:unused
|
||||||
func readTree(c *qt.C, tree *Tree, path string) {
|
func readTree(c *qt.C, tree *Tree, path string) {
|
||||||
b, err := ioutil.ReadFile(path) //nolint:gosec
|
b, err := os.ReadFile(path) //nolint:gosec
|
||||||
c.Assert(err, qt.IsNil)
|
c.Assert(err, qt.IsNil)
|
||||||
err = tree.ImportDump(b)
|
err = tree.ImportDump(b)
|
||||||
c.Assert(err, qt.IsNil)
|
c.Assert(err, qt.IsNil)
|
||||||
@@ -102,7 +101,7 @@ func TestReadTreeDBG(t *testing.T) {
|
|||||||
|
|
||||||
// tree1 is generated by a loop of .Add
|
// tree1 is generated by a loop of .Add
|
||||||
path := "err-dump/tree1-2021-06-03 16:45:54.104449306 +0200 CEST m=+0.073874545.debug"
|
path := "err-dump/tree1-2021-06-03 16:45:54.104449306 +0200 CEST m=+0.073874545.debug"
|
||||||
b, err := ioutil.ReadFile(path)
|
b, err := os.ReadFile(path)
|
||||||
c.Assert(err, qt.IsNil)
|
c.Assert(err, qt.IsNil)
|
||||||
err = importDumpLoopAdd(tree1, b)
|
err = importDumpLoopAdd(tree1, b)
|
||||||
c.Assert(err, qt.IsNil)
|
c.Assert(err, qt.IsNil)
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
qt "github.com/frankban/quicktest"
|
qt "github.com/frankban/quicktest"
|
||||||
@@ -42,7 +42,7 @@ func TestGenerator(t *testing.T) {
|
|||||||
jCvp, err := json.Marshal(cvp)
|
jCvp, err := json.Marshal(cvp)
|
||||||
c.Assert(err, qt.IsNil)
|
c.Assert(err, qt.IsNil)
|
||||||
// store the data into a file that will be used at the circom test
|
// store the data into a file that will be used at the circom test
|
||||||
err = ioutil.WriteFile("go-smt-verifier-inputs.json", jCvp, 0600)
|
err = os.WriteFile("go-smt-verifier-inputs.json", jCvp, 0600)
|
||||||
c.Assert(err, qt.IsNil)
|
c.Assert(err, qt.IsNil)
|
||||||
|
|
||||||
// proof of non-existence
|
// proof of non-existence
|
||||||
@@ -52,6 +52,6 @@ func TestGenerator(t *testing.T) {
|
|||||||
jCvp, err = json.Marshal(cvp)
|
jCvp, err = json.Marshal(cvp)
|
||||||
c.Assert(err, qt.IsNil)
|
c.Assert(err, qt.IsNil)
|
||||||
// store the data into a file that will be used at the circom test
|
// store the data into a file that will be used at the circom test
|
||||||
err = ioutil.WriteFile("go-smt-verifier-non-existence-inputs.json", jCvp, 0600)
|
err = os.WriteFile("go-smt-verifier-non-existence-inputs.json", jCvp, 0600)
|
||||||
c.Assert(err, qt.IsNil)
|
c.Assert(err, qt.IsNil)
|
||||||
}
|
}
|
||||||
|
|||||||
50
tree.go
50
tree.go
@@ -303,7 +303,7 @@ func (t *Tree) addBatchInDisk(wTx db.WriteTx, keys, values [][]byte) ([]Invalid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(subRoots) != nCPU {
|
if len(subRoots) != nCPU {
|
||||||
return nil, fmt.Errorf("This error should not be reached."+
|
return nil, fmt.Errorf("this error should not be reached."+
|
||||||
" len(subRoots) != nCPU, len(subRoots)=%d, nCPU=%d."+
|
" len(subRoots) != nCPU, len(subRoots)=%d, nCPU=%d."+
|
||||||
" Please report it in a new issue:"+
|
" Please report it in a new issue:"+
|
||||||
" https://github.com/vocdoni/arbo/issues/new", len(subRoots), nCPU)
|
" https://github.com/vocdoni/arbo/issues/new", len(subRoots), nCPU)
|
||||||
@@ -1463,9 +1463,11 @@ func (t *Tree) Graphviz(w io.Writer, fromRoot []byte) error {
|
|||||||
// generate a string Graphviz representation of the first NLevels of the tree
|
// generate a string Graphviz representation of the first NLevels of the tree
|
||||||
// and writes it to w
|
// and writes it to w
|
||||||
func (t *Tree) GraphvizFirstNLevels(w io.Writer, fromRoot []byte, untilLvl int) error {
|
func (t *Tree) GraphvizFirstNLevels(w io.Writer, fromRoot []byte, untilLvl int) error {
|
||||||
fmt.Fprintf(w, `digraph hierarchy {
|
if _, err := fmt.Fprintf(w, `digraph hierarchy {
|
||||||
node [fontname=Monospace,fontsize=10,shape=box]
|
node [fontname=Monospace,fontsize=10,shape=box]
|
||||||
`)
|
`); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if fromRoot == nil {
|
if fromRoot == nil {
|
||||||
var err error
|
var err error
|
||||||
fromRoot, err = t.RootWithTx(t.db)
|
fromRoot, err = t.RootWithTx(t.db)
|
||||||
@@ -1482,14 +1484,20 @@ node [fontname=Monospace,fontsize=10,shape=box]
|
|||||||
switch v[0] {
|
switch v[0] {
|
||||||
case PrefixValueEmpty:
|
case PrefixValueEmpty:
|
||||||
case PrefixValueLeaf:
|
case PrefixValueLeaf:
|
||||||
fmt.Fprintf(w, "\"%v\" [style=filled];\n", hex.EncodeToString(k[:nChars]))
|
if _, err := fmt.Fprintf(w, "\"%v\" [style=filled];\n", hex.EncodeToString(k[:nChars])); err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
// key & value from the leaf
|
// key & value from the leaf
|
||||||
kB, vB := ReadLeafValue(v)
|
kB, vB := ReadLeafValue(v)
|
||||||
fmt.Fprintf(w, "\"%v\" -> {\"k:%v\\nv:%v\"}\n",
|
if _, err := fmt.Fprintf(w, "\"%v\" -> {\"k:%v\\nv:%v\"}\n",
|
||||||
hex.EncodeToString(k[:nChars]), hex.EncodeToString(kB[:nChars]),
|
hex.EncodeToString(k[:nChars]), hex.EncodeToString(kB[:nChars]),
|
||||||
hex.EncodeToString(vB[:nChars]))
|
hex.EncodeToString(vB[:nChars])); err != nil {
|
||||||
fmt.Fprintf(w, "\"k:%v\\nv:%v\" [style=dashed]\n",
|
return false
|
||||||
hex.EncodeToString(kB[:nChars]), hex.EncodeToString(vB[:nChars]))
|
}
|
||||||
|
if _, err := fmt.Fprintf(w, "\"k:%v\\nv:%v\" [style=dashed]\n",
|
||||||
|
hex.EncodeToString(kB[:nChars]), hex.EncodeToString(vB[:nChars])); err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
case PrefixValueIntermediate:
|
case PrefixValueIntermediate:
|
||||||
l, r := ReadIntermediateChilds(v)
|
l, r := ReadIntermediateChilds(v)
|
||||||
lStr := hex.EncodeToString(l[:nChars])
|
lStr := hex.EncodeToString(l[:nChars])
|
||||||
@@ -1507,14 +1515,20 @@ node [fontname=Monospace,fontsize=10,shape=box]
|
|||||||
rStr)
|
rStr)
|
||||||
nEmpties++
|
nEmpties++
|
||||||
}
|
}
|
||||||
fmt.Fprintf(w, "\"%v\" -> {\"%v\" \"%v\"}\n", hex.EncodeToString(k[:nChars]),
|
if _, err := fmt.Fprintf(w, "\"%v\" -> {\"%v\" \"%v\"}\n", hex.EncodeToString(k[:nChars]),
|
||||||
lStr, rStr)
|
lStr, rStr); err != nil {
|
||||||
fmt.Fprint(w, eStr)
|
return false
|
||||||
|
}
|
||||||
|
if _, err := fmt.Fprint(w, eStr); err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
fmt.Fprintf(w, "}\n")
|
if _, err := fmt.Fprintf(w, "}\n"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1540,15 +1554,19 @@ func (t *Tree) PrintGraphvizFirstNLevels(fromRoot []byte, untilLvl int) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
w := bytes.NewBufferString("")
|
w := bytes.NewBufferString("")
|
||||||
fmt.Fprintf(w,
|
if _, err := fmt.Fprintf(w,
|
||||||
"--------\nGraphviz of the Tree with Root "+hex.EncodeToString(fromRoot)+":\n")
|
"--------\nGraphviz of the Tree with Root %s:\n", hex.EncodeToString(fromRoot)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
err := t.GraphvizFirstNLevels(w, fromRoot, untilLvl)
|
err := t.GraphvizFirstNLevels(w, fromRoot, untilLvl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(w)
|
fmt.Println(w)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Fprintf(w,
|
if _, err := fmt.Fprintf(w,
|
||||||
"End of Graphviz of the Tree with Root "+hex.EncodeToString(fromRoot)+"\n--------\n")
|
"End of Graphviz of the Tree with Root %s\n--------\n", hex.EncodeToString(fromRoot)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Println(w)
|
fmt.Println(w)
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
54
vt.go
54
vt.go
@@ -171,7 +171,7 @@ func (t *vt) addBatch(ks, vs [][]byte) ([]Invalid, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(nodesAtL) != nCPU {
|
if len(nodesAtL) != nCPU {
|
||||||
return nil, fmt.Errorf("This error should not be reached."+
|
return nil, fmt.Errorf("this error should not be reached."+
|
||||||
" len(nodesAtL) != nCPU, len(nodesAtL)=%d, nCPU=%d."+
|
" len(nodesAtL) != nCPU, len(nodesAtL)=%d, nCPU=%d."+
|
||||||
" Please report it in a new issue:"+
|
" Please report it in a new issue:"+
|
||||||
" https://github.com/vocdoni/arbo/issues/new", len(nodesAtL), nCPU)
|
" https://github.com/vocdoni/arbo/issues/new", len(nodesAtL), nCPU)
|
||||||
@@ -239,7 +239,7 @@ func (n *node) getNodesAtLevel(currLvl, l int) ([]*node, error) {
|
|||||||
return []*node{n}, nil
|
return []*node{n}, nil
|
||||||
}
|
}
|
||||||
if currLvl >= l {
|
if currLvl >= l {
|
||||||
return nil, fmt.Errorf("This error should not be reached."+
|
return nil, fmt.Errorf("this error should not be reached."+
|
||||||
" currLvl >= l, currLvl=%d, l=%d."+
|
" currLvl >= l, currLvl=%d, l=%d."+
|
||||||
" Please report it in a new issue:"+
|
" Please report it in a new issue:"+
|
||||||
" https://github.com/vocdoni/arbo/issues/new", currLvl, l)
|
" https://github.com/vocdoni/arbo/issues/new", currLvl, l)
|
||||||
@@ -627,13 +627,17 @@ func (n *node) computeHashes(currLvl, maxLvl int, p *params, pairs [][2][]byte)
|
|||||||
|
|
||||||
//nolint:unused
|
//nolint:unused
|
||||||
func (t *vt) graphviz(w io.Writer) error {
|
func (t *vt) graphviz(w io.Writer) error {
|
||||||
fmt.Fprintf(w, `digraph hierarchy {
|
if _, err := fmt.Fprintf(w, `digraph hierarchy {
|
||||||
node [fontname=Monospace,fontsize=10,shape=box]
|
node [fontname=Monospace,fontsize=10,shape=box]
|
||||||
`)
|
`); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if _, err := t.root.graphviz(w, t.params, 0); err != nil {
|
if _, err := t.root.graphviz(w, t.params, 0); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Fprintf(w, "}\n")
|
if _, err := fmt.Fprintf(w, "}\n"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -650,7 +654,9 @@ func (n *node) graphviz(w io.Writer, p *params, nEmpties int) (int, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nEmpties, err
|
return nEmpties, err
|
||||||
}
|
}
|
||||||
fmt.Fprintf(w, "\"%p\" [style=filled,label=\"%v\"];\n", n, hex.EncodeToString(leafKey[:nChars]))
|
if _, err := fmt.Fprintf(w, "\"%p\" [style=filled,label=\"%v\"];\n", n, hex.EncodeToString(leafKey[:nChars])); err != nil {
|
||||||
|
return nEmpties, err
|
||||||
|
}
|
||||||
|
|
||||||
k := n.k
|
k := n.k
|
||||||
v := n.v
|
v := n.v
|
||||||
@@ -661,14 +667,20 @@ func (n *node) graphviz(w io.Writer, p *params, nEmpties int) (int, error) {
|
|||||||
v = n.v[:nChars]
|
v = n.v[:nChars]
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintf(w, "\"%p\" -> {\"k:%v\\nv:%v\"}\n", n,
|
if _, err := fmt.Fprintf(w, "\"%p\" -> {\"k:%v\\nv:%v\"}\n", n,
|
||||||
hex.EncodeToString(k),
|
hex.EncodeToString(k),
|
||||||
hex.EncodeToString(v))
|
hex.EncodeToString(v)); err != nil {
|
||||||
fmt.Fprintf(w, "\"k:%v\\nv:%v\" [style=dashed]\n",
|
return nEmpties, err
|
||||||
|
}
|
||||||
|
if _, err := fmt.Fprintf(w, "\"k:%v\\nv:%v\" [style=dashed]\n",
|
||||||
hex.EncodeToString(k),
|
hex.EncodeToString(k),
|
||||||
hex.EncodeToString(v))
|
hex.EncodeToString(v)); err != nil {
|
||||||
|
return nEmpties, err
|
||||||
|
}
|
||||||
case vtMid:
|
case vtMid:
|
||||||
fmt.Fprintf(w, "\"%p\" [label=\"\"];\n", n)
|
if _, err := fmt.Fprintf(w, "\"%p\" [label=\"\"];\n", n); err != nil {
|
||||||
|
return nEmpties, err
|
||||||
|
}
|
||||||
|
|
||||||
lStr := fmt.Sprintf("%p", n.l)
|
lStr := fmt.Sprintf("%p", n.l)
|
||||||
rStr := fmt.Sprintf("%p", n.r)
|
rStr := fmt.Sprintf("%p", n.r)
|
||||||
@@ -685,8 +697,12 @@ func (n *node) graphviz(w io.Writer, p *params, nEmpties int) (int, error) {
|
|||||||
rStr)
|
rStr)
|
||||||
nEmpties++
|
nEmpties++
|
||||||
}
|
}
|
||||||
fmt.Fprintf(w, "\"%p\" -> {\"%v\" \"%v\"}\n", n, lStr, rStr)
|
if _, err := fmt.Fprintf(w, "\"%p\" -> {\"%v\" \"%v\"}\n", n, lStr, rStr); err != nil {
|
||||||
fmt.Fprint(w, eStr)
|
return nEmpties, err
|
||||||
|
}
|
||||||
|
if _, err := fmt.Fprint(w, eStr); err != nil {
|
||||||
|
return nEmpties, err
|
||||||
|
}
|
||||||
nEmpties, err := n.l.graphviz(w, p, nEmpties)
|
nEmpties, err := n.l.graphviz(w, p, nEmpties)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nEmpties, err
|
return nEmpties, err
|
||||||
@@ -707,15 +723,19 @@ func (n *node) graphviz(w io.Writer, p *params, nEmpties int) (int, error) {
|
|||||||
//nolint:unused
|
//nolint:unused
|
||||||
func (t *vt) printGraphviz() error {
|
func (t *vt) printGraphviz() error {
|
||||||
w := bytes.NewBufferString("")
|
w := bytes.NewBufferString("")
|
||||||
fmt.Fprintf(w,
|
if _, err := fmt.Fprintf(w,
|
||||||
"--------\nGraphviz:\n")
|
"--------\nGraphviz:\n"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
err := t.graphviz(w)
|
err := t.graphviz(w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(w)
|
fmt.Println(w)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Fprintf(w,
|
if _, err := fmt.Fprintf(w,
|
||||||
"End of Graphviz --------\n")
|
"End of Graphviz --------\n"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
fmt.Println(w)
|
fmt.Println(w)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user